父類與子類繼承,super關鍵字,方法重寫與重載(學習筆記)

只有禿頭才能變強java

繼承

  • 多個類中存在相同屬性和行爲時,將這些相同的屬性和內容都單獨放在一個類中,那麼多個類就無需定義這些屬性和方法,直接繼承該類
  • 格式:class 子類名 extends 父類名(超類)
    -定義一個類後咱們能夠在一個已經存在的類的基礎上,繼承其屬性和範圍,同時也能夠定義新的屬性和範圍
package Demo1;
//使用繼承後,貓和狗都屬於動物類,都要吃和叫
//因此創建一個動物類
class Animals{
    public void eat() {
        System.out.println("吃");
    }
    public void barking() {
        System.out.println("叫");
    }
}
//貓和狗都繼承動物類
class Cat extends Animals{}
class Dog extends Animals{}

public class ExtendsDemo {
    public static void main(String[] args) {
        //建立一隻小狗,並調用eat和barking方法
        Dog dog=new Dog();
        dog.eat();
        dog.barking();
        //建立一隻小貓,並調用eat和barking方法
        Cat cat=new Cat();
        cat.eat();
        cat.barking();
    }
}
複製代碼

運行結果app




ide

使用繼承的優勢:

  • 提升了代碼的複用性:多個類相同的成員能夠放到一個類中
  • 提升了代碼的維護性:若代碼須要修改,則修改一處便可
  • 讓類與類之間產生關係,是多態的前提

弊端

  • 類的耦合性很強
    設計原則:高內聚低耦合內聚就是本身完成某件事的能力,耦合是類與類之間的關係。咱們在設計的時候原則是這樣的:本身能完成的事情就不麻煩別人,若是未來對方須要修改時,對於咱們的影響比較小。

Java中繼承的特色

  • Java只支持單繼承,不支持多繼承:一個類只能有一個父類,不能夠有多個父類,就比如咱們每一個人只有一個父親。
  • Java支持多層繼承
    class A{}
    class B extends A{}
    class C extends B{}
//Java只支持單繼承,不支持多繼承
class Father{}
class Mother{}
//正確的寫法
class Son extends Father{}
//錯誤的寫法
class Son extends Father and Mother{}
複製代碼
package Demo1;

//Java支持多重繼承
class GrandFather {
    public void say() {
        System.out.println("我是你爺爺");
    }
}

class Father extends GrandFather {
    public void show() {
        System.out.println("我是你爸爸");
    }
}

class Son extends Father {
}

public class ExtendsDemo {
    public static void main(String[] args) {
        // 建立一個兒子對象
        Son son = new Son();
        // 調用父親的方法
        son.show();
        // 調用爺爺的方法
        son.say();
    }
}
複製代碼

運行結果:this

我是你爸爸
我是你爺爺spa

注意事項

  • 子類只能繼承父類的非私有成員(成員方法和成員變量),體現了繼承的另外一個弊端,封裝性。
  • 子類不能繼承父類的構造方法,能夠經過super關鍵字去訪問父類的構造方法。
  • 當知足 is a的關係時能夠考慮使用繼承,如貓是動物的一種,樹是植物的一種
    示例
package Demo1;

class Father {
    private int num = 10;
    public int num1 = 20;

    // 私有方法,子類不能繼承
    private void show() {
        // num能夠在父類中訪問
        System.out.println(num);
        System.out.println(num1);
    }

    public void say() {
        System.out.println(num);
        System.out.println(num1);
    }
}

class Son extends Father {
    public void funtion() {
        // 子類不能繼承父類的私有成員
        // System.out.println(num);
        System.out.println(num1);
    }
}

public class ExtendsDemo {
    public static void main(String[] args) {
        // 建立對象
        Son son = new Son();
        // s.show(),子類不能繼承父類的私有成員方法
        son.say();
        son.funtion();

    }
}
複製代碼

輸出結果
10
20
20設計

繼承中成員變量的關係,當子類中成員變量與父類中的成員變量名稱同樣時,在子類方法中訪問一個變量的查找順序:code

  1. 在子類方法的局部範圍找,有就使用
  2. 在子類的成員範圍找,有就使用
  3. 在父類的成員範圍找,有就使用
  4. 若是都沒有找到,則報錯

super關鍵字

  • super的用法和this的用法很像,super表明父類引用,能夠操做父類的成員。this表明本類對應的引用。
  • 訪問成員變量: this.成員變量:調用本類的成員變量,super.成員變量:調用父類的成員變量。
  • 訪問構造方法:this(…)調用本類的構造方法,super(…)調用父類的構造方法
  • 訪問成員方法:this.成員方法()調用本類的成員方法,super.成員方法()調用父類的構造方法

繼承中構造方法的關係

  • 子類的全部的構造方法都默認訪問父類中空參數的構造方法,子類會繼承父類中的數據,因此在子類初始化以前,必定要先完成父類數據的初始化
  • 注意:子類的每個構造方法第一條默認都是:super()。
package Demo1;

class Father {

   public Father() {
       System.out.println("Father的無參構造");    
   }
   public Father(String name) {
       System.out.println("Father的有參構造");
   }

}

class Son extends Father {
    public Son() {
        //super(),子類的每一個構造方法第一條語句默認super()
        System.out.println("son的無參構造");
    }
    public Son(String name) {
        //super()
        System.out.println("son的有參構造");
    }

}

public class ExtendsDemo {
    public static void main(String[] args) {
        // 建立對象
        Son son = new Son();
        System.out.println("***************");
        Son son2=new Son("tom");

    }
}
複製代碼

輸出結果
Father的無參構造
son的無參構造orm


Father的無參構造
son的有參構造視頻

從運行結果能夠看出,每次建立一個子類對象都會訪問父類的無參構造方法,當父類中沒有無參構造方法時,項目會報錯,解決方法:對象

  1. 在父類中添加一個無參的構造方法
  2. 經過使用super關鍵字顯示地調用父類的帶參構造方法
  3. 子類經過this去調用本類的其餘構造方法
  4. 子類中必定要有一個訪問父類的構造方法,不然父類數據就沒有初始化
  5. 注意事項:
  • this(…)或者super(…)必須出如今語句的第一條,若是不放在語句的第一條,那麼就有可能對父類數據進行屢次初始化,因此必須放在第一條語句上
package Demo1;

class Father {

    /*
     * public Father() { System.out.println("Father的無參構造"); }
     */

    public Father(String name) {
        System.out.println("Father的有參構造");
    }

}

class Son extends Father {
    public Son() {
        super("John");
        System.out.println("son的無參構造");
        // super("John");
    }

    public Son(String name) {
        // super("Jimmy");
        this();
        System.out.println("son的有參構造");
    }

}

public class ExtendsDemo {
    public static void main(String[] args) {
        // 建立對象
        Son son = new Son();
        System.out.println("***************");
        Son son2 = new Son("tom");

    }
}
複製代碼

輸出結果
Father的有參構造
son的無參構造


Father的有參構造
son的無參構造
son的有參構造

繼承中成員方法的關係

  • 若子類中的成員方法與父類中的成員方法同樣,經過子類調用對象的順序爲:先找子類中有沒有這個方法,有就使用,沒有就在父類中找,有就使用,再沒有則報錯

方法的重寫與重載

  • 方法的重寫:子類中出現與父類中如出一轍的方法聲明,也被稱爲方法覆蓋,方法重寫
  • 方法的重載:本類中出現的方法名同樣,參數列表不同的方法,與放回值沒有關係
  • 使用特色:若是方法名不同,就調用對應的方法,若是方法名相同,則使用的是子類的方法
  • 方法重寫的應用:當子類須要父類的功能時,而該父類的功能主體中又有子類本身的內容,此時子類既能夠重寫父類的方法,又定義了子類特有的內容。
  • 注意事項:
    • 父類中的私有方法不能被重寫,由於父類中的私有方法子類根本沒法繼承
    • 子類重寫父類方法時,訪問權限不能更低,最好一致,假設一個父類A擁有的方法爲public void set(){},能夠被其餘任意對象調用,這個方法被子類B覆蓋後寫爲protected void set(){}即默認爲protected的訪問權限,只能被本包及其子類所訪問,假設其餘包中的對象C調用方法爲get(A a){a.set()},而此時傳入的對象爲B類對象,假設B此時轉型爲A,可是B此時set()調用權限已經縮小了將形成錯誤,因此子類對象的訪問修飾要比父類的訪問修飾要大。
package Demo1;

class Laptop extends Pc{
    public void Read(String name) {
        super.Read(name);
        System.out.println("我能夠看視頻");
    }  
}
class Pc{
    public void Read(String name) {
        System.out.println("我能夠看小說");
    }
}
public class ExtendsDemo1 {
    public static void main(String[] args) {
        //建立對象
        Laptop lt=new Laptop();
        lt.Read("哈利波特");
    }

}
複製代碼

輸出結果:
我能夠看小說
我能夠看視頻

方法重寫(override)與重載的區別(overload)

  • 方法重寫:在子類中,出現和父類如出一轍的方法聲明
  • 方法重載:在同一個類中,出現的方法名相同,參數列表不一樣的現象
  • 方法重載能夠改變返回值類型,重寫則不行

渾渾噩噩一天又過去了

相關文章
相關標籤/搜索