面向對象編程有三大特性:封裝、繼承、多態。
【執行順序的優先級:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O),重載[一個類中]和重寫【父子類中】】,
封裝隱藏了類的內部實現機制,可以在不影響使用的情況下改變類的內部結構,同時也保護了數據。對外界而已它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。
繼承是為了重用父類代碼。兩個類若存在IS-A的關系就可以使用繼承。,同時繼承也為實現多態做了鋪墊。那么什么是多態呢?多態的實現機制又是什么?請看我一一為你揭開:
所謂多態就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。因為在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。
比如你是一個酒神,對酒情有獨鐘。某日回家發現桌上有幾個杯子里面都裝了白酒,從外面看我們是不可能知道這是些什么酒,只有喝了之后才能夠猜出來是何種酒。你一喝,這是劍南春、再喝這是五糧液、再喝這是酒鬼酒…。在這里我們可以描述成如下:
酒 a = 劍南春
酒 b = 五糧液
酒 c = 酒鬼酒
…
這里所表現的的就是多態。劍南春、五糧液、酒鬼酒都是酒的子類,我們只是通過酒這一個父類就能夠引用不同的子類,這就是多態——我們只有在運行的時候才會知道引用變量所指向的具體實例對象。相當于一個父親可以由多個兒子,但是,一個兒子只會有一個父親。【多態】
補充:為了更好的理解多態,我們就必須要明白什么是“向上轉型”。在繼承中我們簡單介紹了向上轉型,這里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父類,劍南春(JNC)、五糧液(WLY)、酒鬼酒(JGJ)是子類。我們定義如下代碼:
JNC a = new JNC();
對于這個代碼我們非常容易理解無非就是實例化了一個劍南春的對象嘛!但是這樣呢?
Wine a = new JNC();
在這里我們這樣理解,這里定義了一個Wine 類型的a,它指向JNC對象實例。由于JNC是繼承與Wine,所以JNC可以自動向上轉型為Wine,所以a是可以指向JNC實例對象的。這樣做存在一個非常大的好處,在繼承中我們知道子類是父類的擴展,它可以提供比父類更加強大的功能,如果我們定義了一個指向子類的父類引用類型,那么它除了能夠引用父類的共性外,還可以使用子類強大的功能。
但是向上轉型存在一些缺憾,那就是它必定會導致一些方法和屬性的丟失,而導致我們不能夠獲取它們。所以父類類型的引用可以調用父類中定義的所有屬性和方法,對于只存在與子類中的方法和屬性它就望塵莫及了---1。
java的封裝繼承和多態
this
在每個類的內部,都有一個隱含的成員變量,該類的類型就是該類的類型,該成員變量的名稱是this,this是一個引用,指向自身的對象。
this的用法:
1、this調用本類中的屬性,也就是類中的成員變量
2、this調用本類中的其他方法
3、this調用本類中的其他構造方法,調用時要放在構造方法的首行
面向對象特征之封裝(Encapsulation)
為什么要使用封裝?
1、比如打電話,我們只要按鍵撥打就可以,不需要知道手機的內部結構,也不需要知道怎么打出去
2、比如給手機充電,只要通過手機提供的接口,就可以,不需要知道怎么把電沖進去的
封裝的含義?
1、隱藏對象內部的復雜性,只對外公開簡單的接口,便于外界使用,從而提高系統的擴展性、可維護性
使用訪問權限修飾符,實現封裝
Java用于限定其他對象對該類內部定義的訪問權限
有public、protected 、private、default(不寫)四個
對于class的權限只能使用public 或 default (不寫)
如何實現封裝?
修改屬性的可見性來限制對屬性的訪問。為每個屬性創建一對賦值方法和取值方法,用于對這些屬性的訪問。
在賦值和取值方法中,加入對屬性的存取的限制
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;
}
}
面向對象特征之二 繼承(extends)
繼承:是面向對象的最顯著的一個特征。繼承是從已有的類中派生出新的類,新的類能吸收已有類的數據屬性和行為,并能擴展新的能力
比如上面的動物類,每一個動物都有名字和年齡,都能叫,都會吃。但是具體每一種動物,又有自己特有的屬性和行為,甚至相同的行為,也有千差萬別。
繼承是對某一批類的抽象,從而實現對現實世界更好的建模
提高代碼的復用性
子類繼承父類的語法格式如下:
修飾符 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只支持單繼承,也就是只能繼承一個類
2、如果一個類沒有聲明繼承關系,默認繼承Object類
3、子類繼承父類全部的操作(除了構造方法),如果父類中的屬性是private的,屬于隱
式繼承,不能直接 操作,可以通過set、get方法進行操作
在子類中,可以根據需要對從基類中繼承來的方法進行重寫
重寫方法必須和被重寫方法具有相同的方法名稱、參數列表、和返回類型
重寫方法不能使用比被重寫方法更更嚴格的訪問權限
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訪問父類匯中被子類覆蓋的方法或屬性
普通方法:沒有順序,任意調用
構造方法:任何類的構造方法中,如果構造方法中沒有顯示的調用super(…),那么Java 會默認調
用super()作為父類的初始化方法,所以在寫不寫super()方法,沒 有關系
面向對象特征之三-多態(Polymorphism):多態性是指允許不同軟件元素對同一消息作出響應
把不同的子類對象都當作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。
賦值之后,父類型的引用就可以根據當前賦值給它的子對象的特性以不同的方式運作。也就是說,父親的行為像兒子,而不是兒子的行為像父親
執行期間(非編譯期)判斷所引用的實際類型,根基其實際類型調用相應的方法
父類方法&子類方法都在code Segment中
實際運行調用父類/子類方法?
即由實際運行期創建的對象類型來決定
前提條件:
繼承
復寫
父類引用指向子類
有多態,就可以升高代碼的可擴展性!
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”); //父類引用指向子類對象,向上轉型
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; //強制轉換
System.out.println(d2.folorColor); //將a強制轉換之后,就可以訪問狗里面的屬性了
}
}
評論
查看更多