JAVA-入門 繼承(自學筆記)(郝斌)

繼承

繼承的原則

  • 一個很好的經驗:“類B是類A的一個特殊化嗎?”
  • 如果是則讓類B做類A的子類
class Human
{
    public String name = "彭晨";
    public int age = 22;


}
class Student extends Human
{
    public double score = 99;

}
class Postgraduate extends Student
{

    public String daoshi = "郝斌";

}
class M
{
    public static void main(String[] args)
    {
        Postgraduate  gd = new Postgraduate();
        System.out.printf("%s %d %f %s\n",gd.name,gd.age,gd.score,gd.daoshi);
    }
}

程序運行示例:
————————————————————————————————————————
彭晨 22 99.000000 郝斌
————————————————————————————————————————
  • 一個新類從已有的類那裏獲得其已有的屬性和方法,這種現象叫做類的繼承

  • 這個新類被稱爲子類或者派生類,已有的那個類叫做父類或者叫做基類

  • 繼承的好處

    • 代碼得到極大的重用
    • 形成一種類的層次體系結構
    • 爲多態創造條件(OOP第三個特點)
  • 繼承的實現方式

    • class SubClass extends SuperClass

    • {

    • }

同包繼承權限問題(重點)

  • 子類的所有方法內部都可以訪問父類除私有成員以外的所有成員,所謂子類的所有方法也包括子類的私有方法
  • 通過子類對象名可以訪問
    • 父類除私有成員外的所有成員
    • 子類本身的除私有成員外的所有成員
    • 附註,私有成員包括私有屬性和私有方法
  • 子類可以繼承父類除私有屬性和私有方法以外的所有成員
  • 父類的私有成員不可以被子類繼承,其他的成員都可以被子類繼承
  • 不同包繼承問題等講到包再說!!
class A
{
    public int i;
    protected int j;
    private int k;
    
    public void g()
    {

    }
    protected void f()
    {

    }
    private void b()
    {

    }
}
class B extends A
{
    private void m()
    {
        i = 20;
        j = 30;
        // k =40;  //error k 在 A 中是 private 訪問控制
        g();
        f();
    }

}

class M
{
    public static void main(String[] args)
    {
        B bb = new B();
        bb.i = 10;
        bb.j = 40;
        bb.b();
        bb.m();
        bb.k = 3;

    }
}

程序運行示例:
————————————————————————————————————————
M.java:39: 錯誤: 找不到符號
        bb.b();
          ^
  符號:   方法 b()
  位置: 類型爲B的變量 bb
M.java:40: 錯誤: m() 在 B 中是 private 訪問控制
        bb.m();
          ^
M.java:41: 錯誤: k 在 A 中是 private 訪問控制
        bb.k = 3;
          ^
3 個錯誤
————————————————————————————————————————

子類訪問父類成員的三種方式

  • 在子類內部訪問父類成員
  • 通過子類對象名訪問父類成員
  • 通過子類的類名訪問父類成員

經驗證,子類通過上述三種方式的任何一種都無法訪問父類私有成員,因此我們可以得出結果:

私有成員無法被子類繼承

class A
{
    public static int i;
    protected int j;
    private static int k;
}

class B extends A
{
    public static void g()
    {
        i = 20;
        // k = 20;
    }

}
class M
{
    public static void main(String[] args)
    {
        //B bb = new B();
        //bb.i = 99;//OK
        
    B.g();
    System.out.printf("%d\n",B.k);
    /**
    程序運行示例:
    ———————————————————————————
    k 在 A 中是 private 訪問控制
    System.out.printf("%d\n",B.k);
                              ^
    1 個錯誤 
    ————————————————————————————
    */


    System.out.printf("%d\n",B.i);
    /**
    程序運行示例:
    ———————————————————————————
    20
    ————————————————————————————
    */



    }
}

super()相關

class A
{
    public int i;
    public int j;
    public A()
    {

    }
    public A(int i,int j)
    {
        this.i = i;
        this.j = j;
    }

}

class B extends A
{
    public int k;
    public void f(int i)
    {
        // super(i);
                /**
        程序運行示例:
———————————————————————————————————————
M.java:22: 錯誤: 對super的調用必須是構造器中的第一個語句
        super(i);
             ^
1 個錯誤
————————————————————————————————————————
         */
    }
    public B(int i,int j,int k)
    {

        // this.i = i; //一定要明白爲什麼i前面可以加this
        // this.j = j;



        // A(i,j);
        /**
        程序運行示例:
———————————————————————————————————————
        M.java:24: 錯誤: 找不到符號
        A(i,j);
        ^
  符號:   方法 A(int,int)
  位置: 類 B
1 個錯誤
————————————————————————————————————————
         */


        // super(i,j);//OK
                /**
        程序運行示例:
———————————————————————————————————————
10 39 22
————————————————————————————————————————
         */

        this.k = k;
    }



}
class M
{
    public static void main(String[] args)
    {
        B bb = new B(10,39,22);
        System.out.printf("%d %d %d\n",bb.i,bb.j,bb.k);
  
    }
}

上述代碼總結:

1、 每個子類構造方法的第一條語句,都是隱含地調用super(),如果父類沒有這種形式的構造函數,那麼在編譯的時候 就會報錯。

2、如果顯示的寫出super()語句,則必須保證該語句是第一條語句,否則會出錯

3、super();如果不寫,則編譯器會自動添加,所以此時如果父類沒有無參的構造函數就會出錯。

4、既可以顯示寫super();前提是父類必須有無參的構造函數

5、調用父類的構造函數的語句必須藉助於super(),不能直接寫父類的的類名,該與C++不同

6、一個構造函數中不能寫多個super(參數列表)語句;

總結

  • 私有不能被繼承
  • 私有物理上已經被繼承過來,只不過邏輯上程序員不能去訪問它
  • 因此繼承必須慎重,否則會浪費內存
  • Java只支持單繼承,不允許多重繼承(這一缺陷通過接口來稍稍彌補了一下)
  • 單繼承就是一個類只能有一個父類
  • 多繼承就是一個類可以多個父類
  • 可以有多層繼承,即一個類可以繼承某一個類的子類,如類B繼承了類A,類C又可以繼承類B,那麼類C也間接繼承了類A
  • 子類可以繼承父類所有的成員變量和成員方法,但子類永遠無法繼承父親的構造方法,在子類的構造方法中可使用語句super(參數列表)調用父類的構造方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章