Python 继承与多态

原文: https://thepythonguru.com/python-inheritance-and-polymorphism/


于 2020 年 1 月 7 日更新


继承允许程序员首先创建一个通用类,然后再将其扩展为更专业的类。 它还允许程序员编写更好的代码。

使用继承,您可以继承所有访问数据字段和方法,还可以添加自己的方法和字段,因此继承提供了一种组织代码的方法,而不是从头开始重写代码。

在面向对象的术语中,当X类扩展了Y类时,则Y被称为超类基类,而X被称为子类或派生类。 还有一点要注意,子类只能访问非私有的数据字段和方法,私有数据字段和方法只能在该类内部访问。

创建子类的语法是:

  1. class SubClass(SuperClass):
  2. # data fields
  3. # instance methods

让我们以一个例子来说明这一点。

  1. class Vehicle:
  2. def __init__(self, name, color):
  3. self.__name = name # __name is private to Vehicle class
  4. self.__color = color
  5. def getColor(self): # getColor() function is accessible to class Car
  6. return self.__color
  7. def setColor(self, color): # setColor is accessible outside the class
  8. self.__color = color
  9. def getName(self): # getName() is accessible outside the class
  10. return self.__name
  11. class Car(Vehicle):
  12. def __init__(self, name, color, model):
  13. # call parent constructor to set name and color
  14. super().__init__(name, color)
  15. self.__model = model
  16. def getDescription(self):
  17. return self.getName() + self.__model + " in " + self.getColor() + " color"
  18. # in method getDescrition we are able to call getName(), getColor() because they are
  19. # accessible to child class through inheritance
  20. c = Car("Ford Mustang", "red", "GT350")
  21. print(c.getDescription())
  22. print(c.getName()) # car has no method getName() but it is accessible through class Vehicle

预期输出

  1. Ford MustangGT350 in red color
  2. Ford Mustang

在这里,我们创建了基类Vehicle及其子类Car。 注意,我们没有在Car类中定义getName(),但是我们仍然可以访问它,因为类CarVehicle类继承。 在上面的代码中,super()方法用于调用基类的方法。 这是super()的工作方式

假设您需要在子类的基类中调用名为get_information()的方法,则可以使用以下代码进行调用。

  1. super().get_information()

同样,您可以使用以下代码从子类构造器中调用基类构造器。

  1. super().__init__()

多重继承


与 Java 和 C# 等语言不同,python 允许多重继承,即您可以同时从多个类继承,

  1. class Subclass(SuperClass1, SuperClass2, ...):
  2. # initializer
  3. # methods

让我们举个例子:

  1. class MySuperClass1():
  2. def method_super1(self):
  3. print("method_super1 method called")
  4. class MySuperClass2():
  5. def method_super2(self):
  6. print("method_super2 method called")
  7. class ChildClass(MySuperClass1, MySuperClass2):
  8. def child_method(self):
  9. print("child method")
  10. c = ChildClass()
  11. c.method_super1()
  12. c.method_super2()

预期输出

  1. method_super1 method called
  2. method_super2 method called

如您所见,因为ChildClass继承了MySuperClass1MySuperClass2,所以ChildClass的对象现在可以访问method_super1()method_super2()

覆盖方法


要覆盖基类中的方法,子类需要定义一个具有相同签名的方法。 (即与基类中的方法相同的方法名称和相同数量的参数)。

  1. class A():
  2. def __init__(self):
  3. self.__x = 1
  4. def m1(self):
  5. print("m1 from A")
  6. class B(A):
  7. def __init__(self):
  8. self.__y = 1
  9. def m1(self):
  10. print("m1 from B")
  11. c = B()
  12. c.m1()

预期输出

  1. m1 from B

在这里,我们从基类中重写m1()方法。 尝试在B类中注释m1()方法,现在将运行Base类中的m1()方法,即A类。

预期输出

  1. m1 from A

isinstance()函数


isinstance()函数用于确定对象是否为该类的实例。

语法isinstance(object, class_type)

  1. >>> isinstance(1, int)
  2. True
  3. >>> isinstance(1.2, int)
  4. False
  5. >>> isinstance([1,2,3,4], list)
  6. True

下一章异常处理