1.封裝java
封裝:就是隱藏對象的屬性和實現細節,僅對外提供公共訪問方式。程序員
封裝的好處:隱藏類的實現細節;讓使用者只能經過程序員規定的方法來訪問數據;能夠方便的加入存取控制語句,限制不合理操做.函數
封裝時的權限控制符區別以下:測試
1 /* 2 * 封裝演示 3 */ 4 public class Dog { 5 // 私有化屬性 6 private String name; 7 private String sex; 8 private String color; 9 10 // 封裝字段 11 public String getName() { 12 return name; 13 } 14 15 public void setName(String name) { 16 this.name = name; 17 } 18 19 public String getSex() { 20 return sex; 21 } 22 23 public void setSex(String sex) { 24 this.sex = sex; 25 } 26 27 public String getColor() { 28 return color; 29 } 30 31 public void setColor(String color) { 32 this.color = color; 33 } 34 35 }
Penguin類同理。ui
2.繼承this
語法:spa
修飾符SubClass extends SuperClass{3d
//類定義部分code
}對象
在java中,繼承經過extends關鍵字來實現,其中SubClass稱爲子類,SuperClass稱爲父類。修飾符若是是public,該類在整個項目中可見;不寫public修飾符則該類只在當前包可用;不可使用private和protected修飾符.
繼承:是 java 中實現代碼重用的重要手段之一.java中只支持單繼承,即每一個類只能有一個父類.繼承表達的是 is a 的關係,或者說是一種特殊和通常的關係.
在java中,全部的java類都直接或間的接的繼承了java.lang.long.Object類.Object類是全部java類的祖先.在定義一個類時,沒有使用 extends 關鍵字,那麼這個類直接繼承Object類.
在java中,子類能夠從父類中繼承的有:
繼承 public 和 protected 修飾的屬性和方法,無論子類和父類是否在同一個包裏.
繼承默認權限修飾符修飾的屬性和方法,但子類和父類必須在同一個包裏.
子類沒法繼承父類的有:
沒法繼承 private 修飾的屬性和方法
沒法繼承父類的構造方法
若是從父類繼承的方法不能知足子類的需求,在子類中能夠對父類的同名方法進行重寫 ,以符合要求.
抽象出Dog類和Penguin類和父類Pet類(Pet類爲抽象類,不能被實例化)
/** * Dog和Penguin的父類Pet,而Pet對象是沒有意義的,只是抽象出來的一個概念, 所以給Pet類添* * 加abstract修飾符,讓其成爲一個抽象類,抽象不能被實例化. * */ public abstract class Pet { // 私有化屬性 private String name; private String sex; // 封裝字段 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } // 無參構造方法 public Pet() { } /** * 有參構造方法 * * @param name * 名稱 * @param sex * 性別 * */ public Pet(String name, String sex) { this.setName(name); this.setSex(sex); } // Pet類的抽象方法eat(),抽象方法必需被子類重寫 public abstract void eat(); // final修飾的方法不能被子類重寫 public final void println() { // 方法體… } } // 狗繼承動物類 class Dog extends Pet { private String color; // 封裝字段 public String getColor() { return color; } public void setColor(String color) { this.color = color; } // 無參構造方法 public Dog() { } // 有參構造方法 public Dog(String name, String sex, String color) { // 傳參到父類的構造方法,此處不能用this.name = name..... super(name, sex); // 調用setColor()方法給屬性color賦值 this.setColor(color); } // 重寫父類eat()方法 public void eat() { // 方法體.... } } // 企鵝繼承動物類 class Penguin extends Pet { private double weight; public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } // 重寫父類eat()方法 public void eat() { // 方法體…. } } // 測試類Test class Test { public static void main(String[] args) { String name = "dog1"; String sex = "男"; String color = "red"; // 實例化對象 Dog dog = new Dog(); dog.setName(name); // 經過從父類處繼承來的方法設置dog的屬性name dog.setSex(sex); // 經過有參構造函數實例化對象 Dog dog1 = new Dog("dogName", "man", "black"); // 調用eat()方法,此方法被重寫了 dog1.eat(); } }
繼承條件下構造方法調用規則以下
若是子類的構造方法中沒有經過super顯示調用父類的有參構造方法,也沒有經過this顯示調用自身的其餘構造方法,則系統會默認先調用父類的無參構造 方法.在這種狀況下寫不寫super()語句效果都是同樣.
若是子類的構造方法中經過super顯示調用父類的有參構造方法,那將執行父類相應構造方法,而不執行父類無參構造方法.
若是子類的構造方法中經過this顯示調用自身的其餘構造方法,在相應 構造方法中應用以上兩條規則.
特別注意的是,若是存在多級繼承關係,在建立一個子類對象時,以上規則會屢次向更高一級父類應用,一直到執行頂級父類Object類的無參構造方法爲止.
abstract和final是功能相反的兩個關鍵字,abstract能夠用來修飾類和方法,不能用來修飾屬性和構造方法.final能夠用來修飾類,方法和屬性,不能修飾構造方法.
3.多態
多態的三個條件:
1. 繼承的存在(繼承是多態的基礎,沒有繼承就沒有多態).
2. 子類重寫父類的方法(多態下調用子類重寫的方法).
3. 父類引用變量指向子類對象(子類到父類的類型轉換).
子類轉換成父類時的規則:
將一個父類的引用指向一個子類的對象,稱爲向上轉型(upcastiog),自動進行類型轉換.
此時經過父類引用調用的方法是子類覆蓋或繼承父類的方法,不是父類的方法.
此時經過父類引用變量沒法調用子類特有的方法.
若是父類要調用子類的特有方法就得將一個指向子類對象的父類引用賦給一個子類的引用,稱爲向下轉型,此時必須進行強制類型轉換.
public class Person // 人類 { String name; int age; public void eat() { System.out.println("人們在吃飯!"); } } class Chinese extends Person { // 重寫父類方法 public void eat() { System.out.println("中國人在吃飯!"); } // 子類特有方法,當父類引用指向子類對象時沒法調用該方法 public void shadowBoxing() { System.out.println("練習太極拳!"); } } class English extends Person { // 重寫父類方法 public void eat() { System.out.println("英國人在吃飯!"); } } // 測試類 class TestEat { public static void main(String[] args) { TestEat test = new TestEat(); // 引用指向中國人,建立中國人類對象 Person person1 = new Chinese(); // 此時調用的是Chinese的eat()方法 test.showEat(person1); Person person2 = new English(); // 此時調用的是English的eat()方法 test.showEat(person2); // 強制類型轉換(向下轉型) Chinese chinese = (Chinese) person1; // 向下轉型後,調用子類的特有方法 chinese.shadowBoxing(); } // 使用父類做爲方法的形參,實現多態 public void showEat(Person person) { // 傳入的是哪具對象就調用哪一個對象的eat()方法 person.eat(); } }