7.3 继承和多态
7.3.1 继承
面向对象具有三大特性:封装性、继承性、和多态性。
继承的基本思想是:在一个类的基础上制定出一个新的类、这个新的类可以继承原来类的属性和方法,还可以增加新的属性和方法。原来的类称为父类,新的类被称为子类。一个子类可以有多个父类
在Python中定义子类也很简单,定义子类方法如下:
class SubClass(BaseClass1,BaseClass2):
语法快
定义要从哪个父类继承,只需要在定义子类的名字后面的括号中填入父类名字,如有多个父类则用 , 号隔开
class Animaal:
def __init__(self,name):
self.name = name
def play(self):
print("我是",self.name)
class Dog(Animaal):
pass
dog = Dog("旺财")
dog.play()
执行结果:
我是旺财
继承的时候有两点需要注意:
1.在继承中,如果子类定义了构造方法,则父类的构造方法__init__不会被自动调用,需要在子类的构造方法中专门调用。例如:
class Animal:
def __init__(self,name):
self.name = name
def play(self):
print("我是",self.name)
class Dog(Animal):
def __init__(self):
print("旺财")
dog = Dog()
#错误
dog.play()
如果执行这个例子,会报错,说明 “Animal”的构造方法没有被执行,我们则用 super函数调用 “Animal”的构造方法 如:
class Animal:
def __init__(self,name):
self.name = name
def play(self):
print("我是",self.name)
class Dog(Animal):
def __init__(self):
super(Dog,self).__init__("旺财")
dog = Dog()
dog.play()
执行结果:
我是旺财
(2)子类不能继承父类的私有方法,也不能调用父类的私有方法。
类可以一级一级往下继承,所有的类最终的父类都是“object”
7.3.2 多态
继承可以帮助我们重复使用代码,但是有时候子类的行为不一定和父类一样。
class Animal:
def say(self):
print("Animal")
class Dog(Animal):
def say(self):
print("Dog")
class Cat(Animal):
def say(self):
print("Cat")
dog = Dog()
dog.say()
cat = Cat()
cat.say()
执行结果:
Dog
Cat
这个例子执行:“Dog”和“Cat”分别调用了各自的say方法。
当子类和父类存在相同的方法时,子类的方法会覆盖父类的方法,这样代码在运行时总是调用子类的方法,这就是多态
多态的意思就是多种形态,多态意味着即使不知道变量所引用的对象是什么类型,也能对对象进行操作,多态会根据类的不同而表现出不同的行为。
判断一个实例是不是某个对象可以使用 isinstance 函数 例如:
书本137页!
class Animal:
def say(self):
print("Animal")
class Dog(Animal):
def say(self):
print("Dog")
class Cat(Animal):
def say(self):
print("Cat")
def animal_say(animal:Animal):
animal.say()
dog = Dog()
cat = Cat()
animal_say(dog)
animal_say(cat)
执行结果:
Dog
Cat
从这个例子的执行结果我们发现,aima_say可以不需要关心参数类型到底是什么,只需要关心它们都是“Animal”或者是“Animal”的子类即可,不需要对于函数animal_say进行修改,即可被新的“Animal”子类所使用。
7.33鸭子类型