Java-Review-Note——2.面向?qū)ο?/h1>
標(biāo)簽: JavaStudy
面向?qū)ο罄斫?/h2>
對象引入:
所有事物都具有兩個方面拐揭,有什么彤蔽,能做什么,可以理解為這兩點:
屬性(描述對象) 和 方法(對象功能)
對象設(shè)計的要求:高內(nèi)聚,低耦合伪朽,從而提高對象的可復(fù)用性
對象設(shè)計的思想:以對象為中心,先開發(fā)類,得到對象,再通過對象間的相互通信實現(xiàn)功能
面向?qū)ο蟮膸讉€基本概念:
- 對象:人們要進行研究的任何事物
- 類:具有相同或相似性質(zhì)的對象的抽象
- 對象的狀態(tài)與行為:數(shù)據(jù)與相應(yīng)的操作
- 類的結(jié)構(gòu):類間的結(jié)構(gòu)關(guān)系,"一般---具體 is a"繼承關(guān)系,和"整體---部分" has a"聚集關(guān)系
面對對象的方式:ADP
OOA(分析):產(chǎn)生系統(tǒng)的類和對象行您,描述軟件要做什么
OOD(設(shè)計):OOA的細化铭乾,強調(diào)復(fù)雜系統(tǒng)的正確和有效構(gòu)建,即確定類間的關(guān)系娃循,
對象間的關(guān)系炕檩,類的狀態(tài)轉(zhuǎn)換,模塊間的依賴等捌斧,軟件怎么做
OOP(編碼):三個標(biāo)準(zhǔn)條件:
1.使用對象而非算法作為基本邏輯組件;
2.任意對象都需為某個類的實例
3.類通過繼承關(guān)系與其他類相關(guān)
面向?qū)ο蟮乃拇筇卣?/strong>:
- 封裝(Encapsulation):隱藏對象的實現(xiàn)細節(jié),通過公有方法暴露對象功能
- 多態(tài)(Polymorphism):子類對象可以直接賦值給父類笛质,但運行時表現(xiàn)出子類的行為特征
-
繼承(Inheritance):一個類共享一個或多個類定義的結(jié)構(gòu)與行為,
表示一種泛化/特化的層次關(guān)系 -
抽象(Abstraction):忽略主題中與當(dāng)前目標(biāo)無關(guān)的方面捞蚂,以便更充分地注意與
當(dāng)前目標(biāo)有關(guān)的方面,包含過程抽象與數(shù)據(jù)抽象妇押。
對象
如何創(chuàng)建對象:new關(guān)鍵字 + 指定類名創(chuàng)建
對象的產(chǎn)生:堆中建立對象 -> 棧中創(chuàng)建一個變量引用對象地址
對象與對象的引用:
對象名作為操作的標(biāo)識符,僅僅只是對象的一個引用而已姓迅,而并非對象本身;
有引用敲霍,但不表示一定要有一個對象與引用項鏈俊马,所以在創(chuàng)建一個引用時,
都需要進行初始化肩杈,不初始化直接調(diào)用的話是會NullPointerException的潭袱。
對象的使用:通過點語法訪問.eg:p.age = 18;
對象的生命周期:從new創(chuàng)建開始,到?jīng)]有任何引用到達對象時結(jié)束(成為垃圾)
匿名對象的使用:
不定義變量引用對象,用new創(chuàng)建后直接調(diào)用,沒名字,所以叫做匿名對象
通常我們需要使用一對象,且只用一次的話,就用匿名對象(沒有引用锋恬,
使用一次后就變成垃圾了)可以作為實參進行傳遞
類
類與對象的建模過程:

類的定義:
修飾符 class 類名
{
成員變量
構(gòu)造方法
成員方法
}
成員變量屯换,局部變量與類變量區(qū)別:
成員變量:定義在類中,在整個類中都可以訪問与学,存在于棧內(nèi)存的對象中彤悔,
隨著對象的消失而消失,有默認初始值索守。
局部變量:定義在方法晕窑,語句,局部代碼塊中卵佛,只在所屬區(qū)域有效杨赤;
存在棧內(nèi)存的方法中,隨所屬區(qū)域的執(zhí)行而執(zhí)行截汪;結(jié)束而釋放疾牲,沒有默認初始值。
類變量:static修飾衙解,隨者類加載而加載阳柔,類消失而消失,類變量是所有
對象共有蚓峦,其中一個對象將它值改變舌剂,其他對象得到的就是改變后的結(jié)果
成員變量的初始化:
當(dāng)對象創(chuàng)建時,會對成員變量自動賦初值暑椰,基本數(shù)據(jù)位0霍转,引用型為null;
注:char為"\u0000"表空 boolean:false
構(gòu)造方法(Constructor):
為對象進行初始化的一個特殊方法,在生成對象時會被調(diào)用來初始化對象
構(gòu)造方法名與類名相同一汽,new對象時隱式地進行調(diào)用避消,用戶無法顯式調(diào)用;
無返回值,不能加void返回值類型角虫,總會有的沾谓,就算你不寫構(gòu)造方法;
也會自動生成默認缺省的構(gòu)造方法;當(dāng)然如果寫了戳鹅,就不會再生成了默認的均驶。
構(gòu)造代碼塊:
直接在類中定義切沒有加static關(guān)鍵字的代碼塊,在創(chuàng)建對象時會被調(diào)用枫虏,
每次創(chuàng)建對象都會被調(diào)用妇穴,并且先于構(gòu)造方法執(zhí)行.
普通代碼塊:
在方法或者語句中出現(xiàn)的代碼塊爬虱,先出現(xiàn)先執(zhí)行
靜態(tài)代碼塊:
添加了static聲明的代碼塊,一般用于初始化類腾它,為類屬性初始化跑筝;
會隨著JVM加載類的時加載而執(zhí)行,所以只執(zhí)行一次瞒滴;
不能存在于任何方法體中曲梗,不能直接訪問靜態(tài)實例變量和方法,
需要通過類的示實例對象來訪問
this關(guān)鍵字:
作用:1.區(qū)分局部變量和實例變量妓忍;2.代表本類對象
3.顯式調(diào)用重載的構(gòu)造方法虏两,調(diào)用語句需寫在第一行
比如:
public class Test {
int a;
public Test(){this(1);}
public Test(int i){this.a = i;}
}
成員方法:
一個好的方法應(yīng)該有好的移植性和可重用性
兩種傳參方式:
①按值傳遞:內(nèi)存的空間變量 eg:int i
②按引用傳遞(傳對象引用):Integer類的一個對象引用: Integer i = new Integer(10);
public修飾類的規(guī)則:
一個Java文件,只允許有一個修飾為public的類世剖,接口定罢,枚舉(enum),
且名字要與文件名相同,不然編譯器會報錯!
包的概念:
打包:package eg: package com.jay.example;
導(dǎo)包:import eg:inport java.io.;
注意:導(dǎo)包時用星號只表示該層次的所有類,但是不包含子層次下的類*旁瘫!
繼承
繼承的理解:
比如:學(xué)生祖凫,公務(wù)員,城管酬凳,警察惠况,他們的共性都是人類,我們把人類作為父類粱年,
而把他們作為人類的子類售滤,擁有人類的所有屬性,同時也衍生了一些自己的特性台诗,
比如,城管具有暴力執(zhí)法的特性赐俗。
繼承的方式:子類 extends 父類: eg:class Student extends Person{}
繼承的注意事項:
- 1.Java的數(shù)據(jù)結(jié)構(gòu)是樹形的拉队,所以不像C++可以繼承多個父類,只能單繼承阻逮;
Java通過接口和內(nèi)部類實現(xiàn)多繼承粱快! - 2.父類的私有屬性也繼承,但是不可以直接訪問叔扼,只能通過父類方法進行訪問事哭;
- 3.子類如果想調(diào)用父類的構(gòu)造方法要使用super(參數(shù)),不然會提示找不到瓜富!
其他成員方法用super.xxx訪問鳍咱。 - 4.Object類是所有類的父類。
- 5."先有父親与柑,后有兒子"創(chuàng)建子類對象后谤辜,不用我們自己實例化父類對象蓄坏,系統(tǒng)
會自動創(chuàng)建一個父類對象
子類構(gòu)造對象的順序:
- 從父類到子類,對static成員進行初始化丑念;
- 父類成員變量按順序初始化涡戳,遞歸調(diào)用父類的構(gòu)造方法
- 子類成員變量按順序初始化,子類構(gòu)造方法調(diào)用
super關(guān)鍵字:
需注意:子類中訪問父類的同名成員脯倚,用super語句向父類構(gòu)造方法傳渔彰,
那么super(參數(shù))方法要放在第一句,不然會報錯推正。
多態(tài)
OverLoading:編譯時多態(tài)(方法重載)
同一個類可定義多個同名方法恍涂,各個方法的參數(shù)表一定不同(參數(shù)個數(shù)或類型不同),
返回值也可以不同舔稀,比如:構(gòu)造方法的重載就是編譯時的多態(tài)乳丰。
OverRidding:運行時多態(tài)(方法重定義/覆蓋)
運行時多態(tài) = 繼承 + 重定義 + 動態(tài)綁定
方法覆蓋:
子類方法與父類方法名,參數(shù)表内贮,返回值類型相同
規(guī)律:不能回避比父類方法更多的異常产园,子類訪問控制需比父類更公開
向上轉(zhuǎn)型規(guī)則(UpCasting)
Animal a = new dog(); Dog d = (Dog)a;
問:如果調(diào)用a的叫方法,那么調(diào)用的是Animal的叫還是Dog的叫夜郁?
答:Dog的什燕,new后面是什么類型,動態(tài)類型就是什么類型竞端。
內(nèi)部類
內(nèi)部類:在一個類中又定義了一個類屎即,外面的叫外部類,里面的就叫內(nèi)部類事富,分以下四種:
成員內(nèi)部類技俐,靜態(tài)內(nèi)部類,局部內(nèi)部類统台,匿名內(nèi)部類
使用內(nèi)部類的目的:內(nèi)部類可以直接訪問外部類的成員和方法
注意事項:訪問內(nèi)部類的話需要先創(chuàng)建外部類對象雕擂,接著才可以用它來創(chuàng)建內(nèi)部類對象。
成員內(nèi)部類:
class Outer {
void showInner(){Inner in = new Inner(); in.show();}
class InnerP{
void show(){...}
void test(){...}
}
}
//測試類:
public class InnerTest {
public static void main(String[] args){
Outer out = new Outer();
Outer.Inner in = out.new Inner(); //注意這里的寫法
in.test();
}
}
靜態(tài)內(nèi)部類:
靜態(tài)內(nèi)部類只能訪問外部類的靜態(tài)成員;
創(chuàng)建內(nèi)部類對象不需要外部對象贱勃,直接:new 外部類名.內(nèi)部類的構(gòu)造方法
class Outer{
public static int NUM = 250;
public void outerShow();
static class Inner(){
void innerShow(){ System.out.println("NUM:" + NUM); }
}
}
//測試類:
public class StaticTest{
public static void main(String[] args){
Outer out = new Outer();
out.outerShow();
Outer.Inner in = new Outer.Inner();
in.innerShow();
}
}
局部內(nèi)部類:
局部內(nèi)部類是存在于類中的某個局部井赌,可能是在某個方法或者某個塊語句中
是用的最少的一種內(nèi)部類,和局部變量一樣贵扰,不能夠被public仇穗,protected,private
和static修飾只能夠訪問方法中定義的final類型的局部變量
只能夠在方法中生成局部內(nèi)部類的對象并且調(diào)用它的方法
class Outer{
int a = 1;
public void show(){
int b = 2;
final c = 3;
class Inner{
public void show(){
System.out.println(a); //可以訪問外部類中的變量
System.out.printf(b); //會報錯
System.out.println(a); //可以訪問方法中的final變量
}
}
new Inner().show(); //需在方法中實例化內(nèi)部類對象
}
}
//測試類
public class LoaclTest{
Outer out = new Outer();
out.show();
}
匿名內(nèi)部類:
沒有名稱的內(nèi)部類戚绕,必須是非靜態(tài)的類纹坐,只能用一次;
通常是隱式地繼承一個父類或者實現(xiàn)一個接口
一般用來簡化代碼編寫
//實現(xiàn)抽象方法可以省略一個子類編寫(接口亦是如此)
abstract class A{ public abstract void show(); }
//調(diào)用出直接:
A a = new A(){
public void show(){...}
}
a.show();
比如我們列肢,Android點擊事件的時候我們也常這樣寫:
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) { ... }});
})
抽象類
什么是抽象類:
將具有共同特點的類進行抽象后得到的一個類恰画,這個類本身的方法沒有任何具體實現(xiàn)宾茂;
比如:定義一個抽象的動物類,然后定義幾個抽象方法(動物共有的方法)拴还,比如有設(shè)置
多少只腳的方法:public abstract void setFoots();
抽象類的定義:
使用abstract關(guān)鍵字修飾
抽象類: 修飾符 abstract 類名{//類的內(nèi)容}
抽象方法: 修飾符 abstract 返回值類型 方法名();
抽象類的注意事項:
- 1.如果一個類有一個抽象方法跨晴,那個這個類一定是抽象類。
- 2.雖然一個類是抽象類片林,但可能含非抽象的方法端盆。
- 3.如果類繼承了抽象類,必須重寫抽象類中所有的抽象方法费封,是所有焕妙!如果
沒有全部實現(xiàn)的話,子類也需要定義為抽象類弓摘。 - 4.abstract不能和static一起使用焚鹊,會出現(xiàn)錯誤(因為static不能被覆蓋,而
abstract必須被覆蓋)韧献。 - 5.抽象類不能定義為final末患,abstract不能喝final共存。
- 6.注意區(qū)分方法的空實現(xiàn)和方法的抽象(無實現(xiàn))锤窑!例子如下:
前者:private void show(){} 后者:private void show(); - 7.抽象類不能夠?qū)嵗嫡耄强梢詎ew的時候重寫里面的抽象方法(匿名內(nèi)部類),
或者通過向上轉(zhuǎn)型規(guī)則:Car c = new Track(); 這樣渊啰。
接口
什么是接口探橱?
因為Java的數(shù)據(jù)結(jié)構(gòu)是樹型的,所以不像C++那樣可以同時繼承多個父類;
但是Java通過接口和內(nèi)部類實現(xiàn)了多繼承绘证;接口是一種特殊的抽象類隧膏,
一個類實現(xiàn)一個接口,相當(dāng)于他繼承了一個抽象類嚷那。
接口的定義:修飾符 interface 接口名{"內(nèi)容"}
接口的實現(xiàn):
一個類可以在繼承一個父類的同時實現(xiàn)多個接口私植,用","分隔:
class 類名 extends 父類 implements 接口1,接口2 { ... }
接口的注意事項:
- 1.一個Java文件中只允許有一個public修飾的類车酣,接口,枚舉,且需與文件名同名索绪。
- 2.在一個接口中湖员,所有方法都是公開的,抽象的瑞驱!所有屬性都是公開娘摔,靜態(tài),常量唤反!
- 3.如果一個類生命實現(xiàn)一個接口凳寺,但是沒有實現(xiàn)接口中的所有方法鸭津,那么這個類必須是抽象類!
- 4.接口只關(guān)心功能肠缨,并不關(guān)心功能的具體實現(xiàn)逆趋。
- 5.接口也可以通過extends繼承,但是實現(xiàn)接口時父類子類中所有的抽象方法都需要實現(xiàn)晒奕。
- 6.接口中的方法可以不寫public闻书,但是實現(xiàn)接口中的抽象方法時需要寫上public,不然會報錯脑慧!
修飾符詳解
訪問控制修飾符
- public:公有的魄眉,被public修飾的部分可以被任何程序訪問。
- protected:受保護的闷袒,被它修飾的成員只能由同包中的類或者其子類訪問坑律。
- default(默認):不寫修飾符就是默認的,別寫上defalut澳抑琛晃择!同包與同類可見。
- private:私有的淘捡,是Java實現(xiàn)封裝的關(guān)鍵藕各,被修飾的成員變量與方法只能被類本身訪問,同包也不行焦除!
注意事項:不能使用protected和private來修飾類激况,要么用public,要么不加修飾符膘魄!
static修飾符:
- 1.隨著類的加載而加載乌逐,優(yōu)先于對象存在,被所有的對象所共享创葡,直接被類名所調(diào)用
- 2.靜態(tài)變量:static修飾的變量在所有對象中是共享的浙踢,指向內(nèi)存中同一地址,即任何
對象對變量值的修改都會是存儲空間的值發(fā)生改變灿渴。 - 3.靜態(tài)方法:只能夠訪問靜態(tài)數(shù)據(jù)或者直接調(diào)用靜態(tài)方法洛波,可以直接通過類名進行調(diào)用
- 4.靜態(tài)代碼塊:放在類聲明的內(nèi)部,成員方法與構(gòu)造方法的外部骚露,該代碼塊會在該類第
一次使用時執(zhí)行一次蹬挤,就不會再執(zhí)行了,通常是在這里寫一些初始化的代碼棘幸。 - 5.成員初始化的順序:(靜態(tài)變量焰扳,靜態(tài)初始化塊)->(變量,變量初始化塊)->(構(gòu)造器)
final修飾符:
- 1.修飾常量:public static final int AGE = 10;
- 2.空白final變量:空白的final數(shù)據(jù)成員須在構(gòu)造方法中進行初始化,否則會報錯。
- 3.final常量作為方法的參數(shù)吨悍,只能夠?qū)inal進行簡單的引用扫茅,不能改變常量的值。
- 4.用final來修飾方法:那么該方法為一個不可覆蓋的方法育瓜,如果父類有final修飾的方法,
那么子類繼承同一個方法 - 5.用final來修飾類:那么該類不可以被繼承葫隙,final類沒有子類;同時該類中所有的
方法都默認為final! - 6.final并不涉及繼承爆雹,繼承取決于類的修飾符是public還是其他停蕉,是否可以繼承取決于
該類是否對其子類可見,如果一個方法前有private或static的修飾符,那么系統(tǒng)會在前面自動地
加上final修飾钙态。
abstract抽象修飾符:被abstract修飾的類為抽象類,修飾的方法為抽象方法慧起。
transient:用于修飾不想序列化,持久化的成員
volatile:保證可見性和防止重排序,用的比較少册倒,線程并發(fā)用到蚓挤。
枚舉類型
可以把枚舉enum看成一個普通的類,只是編輯器幫我們做了語法的解析
與編譯而已驻子,你也可以定義一些屬性和方法灿意,但是不能繼承其他類,因為
已經(jīng)繼承了java.lang.Enum崇呵;
簡單用法:(做標(biāo)記缤剧,switch的時候用到)
public enum Color { BLUE,RED,YELLOW; }
//測試類
public EnumTest{
public static void printColor(Color color) {
switch(color) {
case BLUE: System.out.println("藍色"); break;
case RED: System.out.println("紅色"); break;
case YELLOW: System.out.println("黃色"); break;
}
}
public static void main(String[] args) {
printColor(Color.BLUE);
printColor(Color.RED);
printColor(Color.YELLOW);
//也可以用增強for循環(huán)遍歷所有值,調(diào)values()可以獲得枚舉數(shù)組
for(Color c : Color.values()){ System.out.println(c); }
}
}
自定義屬性方法:
public enum Color {
Red("紅色"),BLUE("藍色"),YELLOW("黃色");
private final String value; //私有定義一個成員變量
Color(String value){ this.value = value; } //構(gòu)造方法
public String getValue() { return value; } //定義一個獲取后面值的方法
}
//測試類
public class EnumTest{
public static void main(String[] args) {
//可以通過for循環(huán)調(diào)用獲得枚舉中所有的值
for(Color color : Color.values()) {
System.out.println(color);
System.out.println(color.getValue());
}
//可以調(diào)用ordinal()獲得枚舉值在枚舉中的索引位置域慷,從0開始的
System.out.println(Color.BLUE.ordinal());
//枚舉默認實現(xiàn)了java.lang.Comparable接口,可以直接調(diào)用compareTo對枚舉值進行比較
System.out.println(Color.Red.compareTo(Color.BLUE));
}
}
結(jié)果:RED 紅色 BLUE 藍色 YELLOW 黃色 1 -1