對象的上轉(zhuǎn)型
假設(shè)B是A的子類或者間接子類,用類B創(chuàng)建一個對象换帜,并把這個對象的引用賦值給類A的一個引用,例如:
A a;
B b=new B();
a=b;
等價于
A a=new B();
稱對象a是子類對象b的上轉(zhuǎn)型對象
上轉(zhuǎn)型對象也能強制轉(zhuǎn)換成子類對象
A a;
B b=new B();
a=b;//a是b的上轉(zhuǎn)型對象
b=(B)a;//上轉(zhuǎn)型對象強制轉(zhuǎn)換成子類對象
等價于
A a=new B();
B b=(B)a;
上轉(zhuǎn)型對象可以訪問
父類中被子類繼承的變量
父類中被子類隱藏的變量
父類中被子類繼承的方法
子類中定義的重寫方法
引用對象(子類對象)可以訪問
子類中定義的覆蓋變量
子類中定義的重寫方法
子類中定義的新變量
子類中定義的新方法
如果一個類有很多子類,并且這些子類都重寫了父類中的某個實例方法,把子類創(chuàng)建的對象的引用放到父類的對象中時秀存,就得到了該對象的一個上轉(zhuǎn)型對象,這個上轉(zhuǎn)型對象在調(diào)用這個實例方法時就可能具有多態(tài)性
抽象類
抽象類的特點
定義抽象類的目的是為了其他的類創(chuàng)建一個公共的模板羽氮,讓其他的類對其進(jìn)行繼承
(1)抽象類不能用運算符new創(chuàng)建對象或链。如果要創(chuàng)建對象,必須產(chǎn)生其子類档押,由子類創(chuàng)建對象
(2)抽象類中可以有抽象方法和普通方法澳盐。抽象方法用abstract修飾,只允許聲明令宿,不允許實現(xiàn)
(3)如果一個類中含有抽象方法叼耙,那么這個類必然是抽象類
(4)如果一個非抽象類是一個抽象類的子類,它必須具體實現(xiàn)父類所有的抽象方法粒没,在子類中要將方法前面的abstract去掉
(5)如果一個抽象類是另一個抽象類的子類筛婉,則子類可以實現(xiàn)父類的抽象方法,也可以不實現(xiàn)
去掉非法語句的運行結(jié)果如下:
最終類(fina類)
final類不能被繼承癞松,即不能有子類
final class A{
? ? ? … …
}
A稱為最終類
被final修飾的成員方法不能被重寫
上轉(zhuǎn)型與運行時多態(tài)舉例
接口
接口(interface)的概念
接口可以像類一樣用來對某個概念進(jìn)行抽象
可以用接口進(jìn)行程序的框架設(shè)計倾贰,而不必關(guān)心實現(xiàn)細(xì)節(jié),排除細(xì)節(jié)對框架設(shè)計的干擾
通過接口拦惋,可以實現(xiàn)Java語言本身不具備的類的多重繼承機制,一個類可以實現(xiàn)多個接口
接口的聲明
接口通過使用關(guān)鍵字interface來聲明安寺,接口體中包含常量定義和方法聲明兩部分厕妖。例如:
interface Comparable
{
? ? ? final int negative=-1;
? ? ? final int zero=0;
? ? ? int compare(Comparable another);
}
如果沒有顯示指明,接口中的方法默認(rèn)為是public和abstract的
接口的實現(xiàn)與使用
接口之間可以繼承挑庶,一個接口繼承自另外一個接口言秸,要用關(guān)鍵字extends软能。例如
interface B extends A
{
? ? ? 新方法的聲明
}
一個接口可以繼承自多個接口。注意:類不可以多繼承举畸。接口的多繼承與類的單繼承不沖突
class A{
? ? void f(){//A中實現(xiàn)}
}
classB{
? ? ? void f(){//B中實現(xiàn)}
}
class C extends A,B{
? /*錯誤語法查排,繼承了A的f()方法和B的f()方法。而接口中不會有方法的具體實現(xiàn)抄沮,會在繼承接口的類中重寫該方法跋核,系統(tǒng)調(diào)用的是重寫之后的方法*/
}
一個類通過關(guān)鍵字implements聲明自己實現(xiàn)一個或多個接口,實現(xiàn)多個接口時叛买,用逗號隔開接口名砂代。例如:
class A implements B
class A implements B,C
class Dog extends Animal implements Eatable,Sleepable
接口的使用
如果一個類實現(xiàn)某個接口,那么這個類必須實現(xiàn)該接口的所有方法
如果沒有顯示指明率挣,接口中的方法被默認(rèn)為是public和abstract的刻伊,類在實現(xiàn)接口方法時一定要用public來修飾
接口中定義的常量可以被實現(xiàn)該接口的所有類共享
接口回調(diào)
可以把使用某一接口的類創(chuàng)建的對象的引用賦值給該接口聲明的接口變量中,那么該接口變量就可以調(diào)用被類實現(xiàn)的接口中的方法椒功,當(dāng)接口變量調(diào)用被類實現(xiàn)的接口中方法時捶箱,就是通知相應(yīng)的對象調(diào)用接口的方法,這一過程稱為接口回調(diào)
接口回調(diào)是多態(tài)的一種體現(xiàn)动漾,不同的類在實現(xiàn)同一接口時丁屎,可能具有不同的功能體現(xiàn),因此接口回調(diào)可能產(chǎn)生不同的行為
抽象類與接口的比較
抽象類中可以有抽象方法和普通方法谦炬,接口中的所有方法必須是抽象的
抽象類中可以有常量也可以有變量悦屏,接口中不能有變量
一個類可以實現(xiàn)多個接口,但是只能繼承一個抽象類
接口與實現(xiàn)它的類不構(gòu)成類的繼承體系键思,而抽象類屬于一個類的繼承體系
內(nèi)部類
在一個類中聲明的類础爬,稱為內(nèi)部類
包含內(nèi)部類的類稱為外嵌類
一個類把內(nèi)部類看成是自己的成員
外嵌類的成員變量在內(nèi)部類中仍然有效
內(nèi)部類中的方法也可以調(diào)用外嵌類中的方法
內(nèi)部類的類體中不可以聲明類變量和類方法
外嵌類可以把內(nèi)部類聲明的對象作為外嵌類的成員
在方法中聲明內(nèi)部類
在方法的內(nèi)部,有時需要一個類來支撐算法吼鳞,但這個類僅在這個方法中需要看蚜,在別的地方不需要;或者別的地方有同名的類赔桌;或者存在類似功能的類供炎,但希望名稱不一樣等;這些情況需要在方法中建立一個內(nèi)部類
匿名類
與類有關(guān)的匿名類
子類對象的創(chuàng)建和子類類體定義同時進(jìn)行的類稱為匿名類
匿名類是一個子類疾党,由于無名可用音诫,所以不能用匿名類聲明對象,但是可以用匿名類創(chuàng)建對象
假設(shè)A是一個類雪位,則下列代碼就是類A的一個子類(匿名類)創(chuàng)建對象
new A()
{
? ? … …
}
匿名類可以繼承類的方法竭钝,也可以重寫類的方法
匿名類是內(nèi)部類,在某個類中直接使用匿名類創(chuàng)建對象
匿名對象的引用必須傳遞給一個匹配的參數(shù)
假設(shè)f( A a)是一個方法,其中的參數(shù)a是A類對象香罐,在調(diào)用方法f()時可以向參數(shù)a傳遞一個匿名對象
f(new A()
{
? ? … …
});
與接口有關(guān)的匿名類
假設(shè)Comparable是一個接口卧波,Java允許直接用接口名和一個類體創(chuàng)建一個匿名對象,此類體被認(rèn)為是實現(xiàn)了Comparable接口的類去掉類聲明后的類體庇茫,即匿名類
new Comparable()
{
? ? ? ? ? … …
}
假設(shè)f(Comparable x)是一個方法港粱,其中的參數(shù)是接口變量,在調(diào)用方法f()時可以向參數(shù)x傳遞一個匿名對象
f(new Comparable()
{
? ? ? … …
});