面向?qū)ο?a target="_blank">編程有三大特性:封裝、繼承、多態(tài)。
【執(zhí)行順序的優(yōu)先級:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O),重載[一個(gè)類中]和重寫【父子類中】】,
封裝隱藏了類的內(nèi)部實(shí)現(xiàn)機(jī)制,可以在不影響使用的情況下改變類的內(nèi)部結(jié)構(gòu),同時(shí)也保護(hù)了數(shù)據(jù)。對外界而已它的內(nèi)部細(xì)節(jié)是隱藏的,暴露給外界的只是它的訪問方法。
繼承是為了重用父類代碼。兩個(gè)類若存在IS-A的關(guān)系就可以使用繼承。,同時(shí)繼承也為實(shí)現(xiàn)多態(tài)做了鋪墊。那么什么是多態(tài)呢?多態(tài)的實(shí)現(xiàn)機(jī)制又是什么?請看我一一為你揭開:
所謂多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量倒底會指向哪個(gè)類的實(shí)例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定。因?yàn)樵诔绦蜻\(yùn)行時(shí)才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實(shí)現(xiàn)上,從而導(dǎo)致該引用調(diào)用的具體方法隨之改變,即不修改程序代碼就可以改變程序運(yùn)行時(shí)所綁定的具體代碼,讓程序可以選擇多個(gè)運(yùn)行狀態(tài),這就是多態(tài)性。
比如你是一個(gè)酒神,對酒情有獨(dú)鐘。某日回家發(fā)現(xiàn)桌上有幾個(gè)杯子里面都裝了白酒,從外面看我們是不可能知道這是些什么酒,只有喝了之后才能夠猜出來是何種酒。你一喝,這是劍南春、再喝這是五糧液、再喝這是酒鬼酒…。在這里我們可以描述成如下:
酒 a = 劍南春
酒 b = 五糧液
酒 c = 酒鬼酒
…
這里所表現(xiàn)的的就是多態(tài)。劍南春、五糧液、酒鬼酒都是酒的子類,我們只是通過酒這一個(gè)父類就能夠引用不同的子類,這就是多態(tài)——我們只有在運(yùn)行的時(shí)候才會知道引用變量所指向的具體實(shí)例對象。相當(dāng)于一個(gè)父親可以由多個(gè)兒子,但是,一個(gè)兒子只會有一個(gè)父親。【多態(tài)】
補(bǔ)充:為了更好的理解多態(tài),我們就必須要明白什么是“向上轉(zhuǎn)型”。在繼承中我們簡單介紹了向上轉(zhuǎn)型,這里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父類,劍南春(JNC)、五糧液(WLY)、酒鬼酒(JGJ)是子類。我們定義如下代碼:
JNC a = new JNC();
對于這個(gè)代碼我們非常容易理解無非就是實(shí)例化了一個(gè)劍南春的對象嘛!但是這樣呢?
Wine a = new JNC();
在這里我們這樣理解,這里定義了一個(gè)Wine 類型的a,它指向JNC對象實(shí)例。由于JNC是繼承與Wine,所以JNC可以自動向上轉(zhuǎn)型為Wine,所以a是可以指向JNC實(shí)例對象的。這樣做存在一個(gè)非常大的好處,在繼承中我們知道子類是父類的擴(kuò)展,它可以提供比父類更加強(qiáng)大的功能,如果我們定義了一個(gè)指向子類的父類引用類型,那么它除了能夠引用父類的共性外,還可以使用子類強(qiáng)大的功能。
但是向上轉(zhuǎn)型存在一些缺憾,那就是它必定會導(dǎo)致一些方法和屬性的丟失,而導(dǎo)致我們不能夠獲取它們。所以父類類型的引用可以調(diào)用父類中定義的所有屬性和方法,對于只存在與子類中的方法和屬性它就望塵莫及了---1。
java的封裝繼承和多態(tài)
this
在每個(gè)類的內(nèi)部,都有一個(gè)隱含的成員變量,該類的類型就是該類的類型,該成員變量的名稱是this,this是一個(gè)引用,指向自身的對象。
this的用法:
1、this調(diào)用本類中的屬性,也就是類中的成員變量
2、this調(diào)用本類中的其他方法
3、this調(diào)用本類中的其他構(gòu)造方法,調(diào)用時(shí)要放在構(gòu)造方法的首行
面向?qū)ο筇卣髦庋b(Encapsulation)
為什么要使用封裝?
1、比如打電話,我們只要按鍵撥打就可以,不需要知道手機(jī)的內(nèi)部結(jié)構(gòu),也不需要知道怎么打出去
2、比如給手機(jī)充電,只要通過手機(jī)提供的接口,就可以,不需要知道怎么把電沖進(jìn)去的
封裝的含義?
1、隱藏對象內(nèi)部的復(fù)雜性,只對外公開簡單的接口,便于外界使用,從而提高系統(tǒng)的擴(kuò)展性、可維護(hù)性
使用訪問權(quán)限修飾符,實(shí)現(xiàn)封裝
Java用于限定其他對象對該類內(nèi)部定義的訪問權(quán)限
有public、protected 、private、default(不寫)四個(gè)
對于class的權(quán)限只能使用public 或 default (不寫)
如何實(shí)現(xiàn)封裝?
修改屬性的可見性來限制對屬性的訪問。為每個(gè)屬性創(chuàng)建一對賦值方法和取值方法,用于對這些屬性的訪問。
在賦值和取值方法中,加入對屬性的存取的限制
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age 》 200){
throw new RuntimeException(“老妖怪。。.。”);
}
this.age = age;
}
}
面向?qū)ο筇卣髦?繼承(extends)
繼承:是面向?qū)ο蟮淖铒@著的一個(gè)特征。繼承是從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為,并能擴(kuò)展新的能力
比如上面的動物類,每一個(gè)動物都有名字和年齡,都能叫,都會吃。但是具體每一種動物,又有自己特有的屬性和行為,甚至相同的行為,也有千差萬別。
繼承是對某一批類的抽象,從而實(shí)現(xiàn)對現(xiàn)實(shí)世界更好的建模
提高代碼的復(fù)用性
子類繼承父類的語法格式如下:
修飾符 class subclass extends superclass {…。。}
public class Animal {
private String name;
private int age;
public void shout(){
System.out.println(“我的叫聲很好聽。。”);
}
//省略get、set方法
}
public class Dog extends Animal{
public void eat() {
System.out.println(“我吃骨頭。..”);
}
}
Java繼承:
1、Java只支持單繼承,也就是只能繼承一個(gè)類
2、如果一個(gè)類沒有聲明繼承關(guān)系,默認(rèn)繼承Object類
3、子類繼承父類全部的操作(除了構(gòu)造方法),如果父類中的屬性是private的,屬于隱
式繼承,不能直接 操作,可以通過set、get方法進(jìn)行操作
在子類中,可以根據(jù)需要對從基類中繼承來的方法進(jìn)行重寫
重寫方法必須和被重寫方法具有相同的方法名稱、參數(shù)列表、和返回類型
重寫方法不能使用比被重寫方法更更嚴(yán)格的訪問權(quán)限
public class Animal {
private String name;
private int age;
public void shout(){
System.out.println(“動物會叫。.”);
}
}
public class Dog extends Animal{
public void eat() {
System.out.println(“我吃骨頭。..”);
}
@Override
public void shout() {
System.out.println(“汪汪。。汪汪。。。”);
}
}
Super:是直接父類對象的引用可以通過super訪問父類匯中被子類覆蓋的方法或?qū)傩?/p>
普通方法:沒有順序,任意調(diào)用
構(gòu)造方法:任何類的構(gòu)造方法中,如果構(gòu)造方法中沒有顯示的調(diào)用super(…),那么Java 會默認(rèn)調(diào)
用super()作為父類的初始化方法,所以在寫不寫super()方法,沒 有關(guān)系
面向?qū)ο筇卣髦?多態(tài)(Polymorphism):多態(tài)性是指允許不同軟件元素對同一消息作出響應(yīng)
把不同的子類對象都當(dāng)作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應(yīng)需求的不斷變化。
賦值之后,父類型的引用就可以根據(jù)當(dāng)前賦值給它的子對象的特性以不同的方式運(yùn)作。也就是說,父親的行為像兒子,而不是兒子的行為像父親
執(zhí)行期間(非編譯期)判斷所引用的實(shí)際類型,根基其實(shí)際類型調(diào)用相應(yīng)的方法
父類方法&子類方法都在code Segment中
實(shí)際運(yùn)行調(diào)用父類/子類方法?
即由實(shí)際運(yùn)行期創(chuàng)建的對象類型來決定
前提條件:
繼承
復(fù)寫
父類引用指向子類
有多態(tài),就可以升高代碼的可擴(kuò)展性!
class Animal{
public String name;
public Animal(String name){
this.name = name;
}
}
class Dog extends Animal{
public String folorColor;
public Dog(String name,StringfolorColor){
super(name); this.folorColor = folorColor;
}
}
class Cat extends Animal{
public String eyesColor;
public Cat(String name,String eyesColor){
super(name); this.eyesColor = eyesColor;
}
}
public class TestCasting{
public static void main(String args[]){
Animal a = new Animal(“a”);
Cat c = new Cat(“c”,“cEyesColor”);
Dog d = new Dog(“d”,“dForlorColor”);
System.out.println(a instanceof Animal); //true
System.out.println(c instanceof Animal); //true
System.out.println(d instanceof Animal); //true
System.out.println(a instanceof Dog); //false
a = new Dog(“d2”,“d2ForlorColor”); //父類引用指向子類對象,向上轉(zhuǎn)型
System.out.println(a.name); //可以訪問
//System.out.println(a.folorColor);
//!error 不可以訪問超出Animal自身的任何屬性
System.out.println(a instanceof Animal); //是一只動物 System.out.println(a instanceof Dog); //是一只狗,但是不能訪問狗里面的屬性
Dog d2 = (Dog)a; //強(qiáng)制轉(zhuǎn)換
System.out.println(d2.folorColor); //將a強(qiáng)制轉(zhuǎn)換之后,就可以訪問狗里面的屬性了
}
}
評論
查看更多