多型

func1(obj: Animal) 函式的參數,可以是 Dog 類別或 Cat 類別,只要類別有繼承Animal就可以。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("汪汪汪")

class Cat(Animal):
    def speak(self):
        print("喵喵喵")

def func1(obj: Animal):
    obj.speak()

func1(Dog())
func1(Cat())
汪汪汪
喵喵喵

判斷多型 isinstance()

使用isinstance()函式,可以判斷類型。

語法:

isinstance(obj, 類型)
isinstance(obj, (類型1, 類型2, 類型3))

可以判斷obj是不是某個類型,也可以比較是不是屬於多個類型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("汪汪汪")

class Cat(Animal):
    def speak(self):
        print("喵喵喵")

def func1(obj: Animal):
    obj.speak()

cat = Cat()
dog = Dog()
print(f"cat 是不是 Animal? {isinstance(cat, Animal)}")
print(f"dog 是不是 Animal? {isinstance(dog, Animal)}")
print(f"dog 是不是 Dog和Animal? {isinstance(dog, (Animal, Dog))}")
cat 是不是 Animal? True
dog 是不是 Animal? True
dog 是不是 Dog和Animal? True

c++ vs java vs python

Prerequisites:

Python的多型,在成員變數的部分,跟C++與Java不一樣。

C++ 多型

Parent與Child都有相同成員變數name,但子類別沒有覆寫Parent的hi()函式,執行結果為Parent的name。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include "main.h"
using namespace std;
class Parent {
 public:
  string name = "Parent";
  virtual void hi() {
    cout << "name = " << this->name << endl;
  }
};
class Child:public Parent {
 public:
  string name = "Child";
};
int main() {
  Parent* ptr = new Child;
  ptr->hi();
  return 0;
}
Parent

Java 多型

Parent與Child都有相同成員變數name,但子類別沒有覆寫Parent的hi()函式,執行結果為Parent的name。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
  public static void main(String[] args) {
    Parent obj = new Child();
    obj.hi();
  }
}
class Parent {
  String name = "Parent";
  public void hi() {
    System.out.println("name = " + this.name);
  }
}
class Child extends Parent{
  String name = "Child";
}
name = Parent

Python 多型

Parent與Child都有相同成員變數name,但子類別沒有覆寫Parent的hi()函式,執行結果為Child的name。

1
2
3
4
5
6
7
8
9
10
11
class Parent:
    name = "Father"

    def hi(self):
        print("name =", self.name)

class Child(Parent):
    name = "Child"

obj = Child()
obj.hi()
name = Child

Python vs Java vs C++

Python在讀取 self.name 成員變數,先從子類別Child找,有這個屬性就取得。
如果子類別沒有name屬性,就去父類別找,如果仍找不到就去祖父類別找,直到找到為止。

Java 與 C++:
執行誰的方法,就是使用誰的成員變數。
執行父類別的方法,使用父類別的成員變數。
執行子類別的方法,使用子類別的成員變數。

因為Child類別沒有hi()方法,就會去執行父類別的hi()方法,就會使用父類別的name成員變數。

results matching ""

    No results matching ""