1. 程式人生 > 實用技巧 >Java 封裝繼承多型

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強制轉換之後,就可以訪問狗裡面的屬性了
     }
}