多型

向上轉型物件Upcasting object

使用子類別的建立物件的建構子,「產生出父類別的物件」,稱之為向上轉型物件Upcasting object。

以下的方式,都是產生出向上轉型物件,注意!這裡不是產生子類物件,而是產生「向上轉型物件」。

建立向上轉型物件,方式1

1
2
3
Parent parent;
Child child = new Child();
parent = child;

建立向上轉型物件,方式2

1
2
Parent parent;
parent = new Child();

建立向上轉型物件,方式3

1
Parent parent = new Child();

向上轉型物件存取範圍

向上轉型物件,無法呼叫子類別自己擁有成員變數與成員方法,只能呼叫子類別繼承的方法與變數,以及子類別「override覆寫」父類別的方法與變數。

向上轉型物件不等於父類別

由子類別建立的向上轉型物件,不等於父類別。

父類別可以存取自己的成員變數與成員方法,子類別也可以存取自己的成員變數與成員方法,但向上轉型物件無法讀取自己的成員變數與成員方法,因此向上轉型物件不等於父類別也不等於子類別。

向上轉型物件範例1

以下Parent類別有name與age成員變數,與2個建構子。

1
2
3
4
5
6
7
8
public class Parent {
  String name;
  int age;
  Parent(){}
  Parent(String name) {
    this.name = name;
  }
}

Child類別除了繼承父類,有name與age成員變數,與2個建構子。
Child類別自己有address成員變數與getAddress()與setAddress()二個成員方法,並非來自繼承得到。

1
2
3
4
5
6
7
8
9
10
11
12
public class Child extends Parent{
  String address;
  public String getAddress() {
    return address;
  }
  public void setAddress(String address) {
    this.address = address;
  }
  Child(String name) {
    this.name = "child_" + name;
  }
}

建立向上轉型物件

1
Parent upcasting_obj = new Child("Alice");

upcasting_obj是向上轉型物件,即使是用「子類別的建構子」產生的「父類別物件」,但是upcasting_obj向上轉型物件缺少了address成員變數與getAddress()與setAddress()二個成員方法,但有覆寫的Child(String name)建構子,與覆寫的name成員變數。

驗證向上轉型物件擁有繼承來的name變數

1
2
3
4
5
6
7
8
9
10
11
12
public class Teest {
  public static void main(String[] args) {
    Parent upcasting_obj = new Child("Alice");
    // 擁有子類別覆寫的建構子Child(String name)
    // 擁有繼承來的name變數
    System.out.println(upcasting_obj.name);
    // 以下的都無法呼叫子類別自己擁有的成員變數與成員方法
    //upcasting_obj.setAddress("xxx");
    //upcasting_obj.getAddress();
    //System.out.println(upcasting_obj.address);
  }
}
child_Alice

向上轉型物件範例2

1
2
3
public class People {
    public void speak() {}
}

美國人

1
2
3
4
5
6
7
8
9
public class American extends People{
    @Override
    public void speak() {
        System.out.println("speak English.");
    }
    public void goChurch() {
        System.out.println("go to Church.");
    }
}

中國人

1
2
3
4
5
6
7
8
9
public class Chinese extends People{
    @Override
    public void speak() {
        System.out.println("說中文");
    }
    public void tombSweeping() {
        System.out.println("掃墓");
    }
}

日本人

1
2
3
4
5
6
7
8
9
public class Japanese extends People{
    @Override
    public void speak() {
        System.out.println("說日文");
    }
    public void dollFestival() {
        System.out.println("女兒節.");
    }
}

建立向上轉型物件,僅能呼叫子類別覆寫父類別的speak()方法,向上轉型物件不能呼叫子類別特有的goChurch(),tombSweeping(),dollFestival()

1
2
3
4
5
6
7
8
9
10
public class Test {
  public static void main(String[] args) {
    People upcasting_obj1 = new Chinese();
    upcasting_obj1.speak();
    People upcasting_obj2 = new American();
    upcasting_obj2.speak();
    People upcasting_obj3 = new Japanese();
    upcasting_obj3.speak();
  }
}
說中文
speak English.
說日文

向下轉型物件

將父類別物件向下轉型成子類別。

向上轉型的定義是,使用子類別的建立物件的建構子,「產生出父類別的物件」。

這次我們將把「產生出父類別的物件」,向下轉型成子類別。

自動轉型

由於向上轉型只會有一個父類別,因為每個類別只能繼承一個父類別,因此使用自動轉型。

1
2
3
4
Parent parent;
Child child = new Child();
// 以下是自動轉型
parent = child;

強制轉型

父類別下面會有多個子類別,不確定要轉成那個子類別,因此採用強制轉型,也就是使用括號,括號中是要轉型的(子類別)。

1
2
3
People upcasting_obj1 = new Chinese();
// 強制轉型成子類別
Chinese chinese = (Chinese) upcasting_obj1;

強轉成子類物件

強轉回子類物件又會擁有子類別特有的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test {
  public static void main(String[] args) {
    People upcasting_obj1 = new Chinese();
    upcasting_obj1.speak();
    People upcasting_obj2 = new American();
    upcasting_obj2.speak();
    People upcasting_obj3 = new Japanese();
    upcasting_obj3.speak();

    System.out.println("------強轉成子類別----------");
    Chinese chinese = (Chinese) upcasting_obj1;
    chinese.tombSweeping();
    American american = (American) upcasting_obj2;
    american.goChurch();
    Japanese japanese = (Japanese) upcasting_obj3;
    japanese.dollFestival();
  }
}
說中文
speak English.
說日文
------強轉成子類別----------
掃墓
go to Church.
女兒節.

多型

所謂的多型就是,父類別可以指向多種不同子類別,父類別可以使用「子類別覆寫父類別的方法」。
範例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Test {
  public static void main(String[] args) {
    People people = new People();
    // 父類別指向美國人
    people = new American();
    // 使用子類別覆寫父類別的方法
    people.speak();

    // 父類別指向中國人
    people = new Chinese();
    // 使用子類別覆寫父類別的方法
    people.speak();

    // 父類別指向日本人
    people = new Japanese();
    // 使用子類別覆寫父類別的方法
    people.speak();
  }
}
speak English.
說中文
說日文

results matching ""

    No results matching ""