1. 程式人生 > >面向物件——繼承和多型

面向物件——繼承和多型

面向物件——繼承和多型

一. 繼承

1.繼承:

是一種機制,可以進行程式碼的重用——基類(超類) 子類(派生類)   子類繼承了 父類的除建構函式外的所有屬性

2.super關鍵字:

  • super():----->呼叫基類的建構函式 //必須放在第一行
  • super.data------->訪問基類的資料成員
  • super.func();—>呼叫基類的成員方法
class Base{
    protected int a;
    public Base (int a){
        fun1();
        this.a=a;
    }
    public void fun1() {
        System.out.println("Base.fun1()"+ this.a);
    }
}
class Childern extends Base{
    private int b;
    public Childern(int a,int b) {
        super(a);
        super.a = 10;
        super.fun1();
        a=10;
        this.b=b;
        System.out.println("Childern.init()...");
    }
    public void fun1() {
        System.out.println("Childern.fun1()");
    }

    public void fun1(int a) {
        System.out.println("Childern.fun1(int)");
    }
}

3.派生類構造物件的初始化順序

class Base{
    protected int a;
    public Base (int a){
        fun1();
        System.out.println("Base.init()...");
        this.a=a;
    }
    static {
        System.out.println("Base.static...");
    }
    {
        System.out.println("Base.instance...");
    }
    public
void fun1(){ System.out.println("Base.fun1()..."+this.a); } public static void fun2(){ System.out.println("Base.fun2()..."); } } class Childern extends Base{ private int b; public Childern(int a,int b) { super(a); a=10; this.b=b; System.
out.println("Childern.init()..."); } static { System.out.println("Childern.static..."); } { System.out.println("Childern.instance..."); } public void fun1(){ System.out.println("Childern.fun1()..."); } public void fun1(int a){ System.out.println("Childern.fun1(int)..."); } public static void fun2(){ System.out.println("Childern.fun2()..."); } } public class Test1031_2 { public static void main(String[] args) { Base base =new Childern(1,2); }

列印結果為:

Base.static...
Childern.static...
Base.instance...
Childern.fun1()...
Base.init()...
Childern.instance...
Childern.init()...

可以看出派生類構造物件的初始化順序:

  1. 基類的靜態塊初始化,
  2. 派生類的靜態塊初始化
  3. 基類的例項塊初始化
  4. 基類的建構函式
  5. 派生類的例項塊初始化
  6. 派生類的建構函式

4.基類的資料成員在派生類當中的訪問許可權

同包子類 同包非子類 不同包子類 不同包非子類
public 可以 可以 可以 可以
private 不可以 不可以 不可以 不可以
protected 可以 可以 不可以 不可以
預設許可權 可以 可以 不可以 不可以

5.基類和派生類之間的相互賦值

派生類的值可以賦值給基類;

但是基類的值不能賦值給派生類

例如:上面那段程式碼 然後主函式改成:

public static void main1(String[] args) {
        Base base = new Base(1);

        Childern childern = new Childern(1,2);
        base = childern;//這句就是正確的
        childern = base;//這句就是錯誤的,error
    }

6.過載overlode; 函式名相同,引數列表不相同,與函式返回值無關  並不一定在同一個類當中;繼承關係上也可以構成過載;

重寫/覆蓋overwrite;函式名相同,引數列表相同,函式返回值相同

三.多型:

基類引用了派生類物件,並且基類和派生類有同名的覆蓋方法

動多型:發生在執行的時候

靜多型:發生在編譯的時候

方法表是在編譯的時候生成的,

一般的物件放在堆裡 class物件例外放在方法區

方法表和型別一一對應

public static void main2(String[] args) {
        Base base=new Base(1);
        Childern childern=new Childern(1,2);
        base=childern;
    }

    public static void main3(String[] args) {
        Base base=new Base(1);
        base.fun1();
        System.out.println("===============");
        Childern childern=new Childern(1,2);
        childern.fun1();
    }

    public static void main4(String[] args) {
        Base base=new Childern(1,2);
        base.fun1();//動多型  執行的時候
        Base.fun2();//靜多型  編譯的時候