标签:lis 设置 ref 开放 构造函数 ima 方便 父类 false
2018/6/26 星期二 11:15:57
继承的语法:
class Animal(object):
def run(self):
print("Animal is runnung...")
# Animal 继承于object,第一个类都继承于object,不管你写不写`object`
class Dog(Animal):
pass
# Dog继承于Animal
class Cat(Animal):
pass
# Cat继承于Animal
Dog
来说,Animal
就是它的父类,对于Animal
来说,Dog
就是它的子类继承的好处就在于子类获得了父类的全部功能。Dog
也有了Animal
的Run()
方法
>>> dog = Dog()
# 子类一旦继承父类,则可以使用父类中除私有成员外的所有内容
>>> dog.run
Animal is runnung...
我们对上面代码再次进行改进,给Dog
和Cat
添加一些方法
class Dog(Animal):
def run(self):
print(‘Dog is running...‘)
class Cat(Animal):
def run(self):
print(‘Cat is running...‘)
运行:
>>> dog = Dog()
>>> cat = Cat()
>>> dog.run()
>>> cat.run()
Dog is running...
Cat is running...
我们可以看到这里,子类和父类都存在run
方法时,子类的run()
覆盖了父类的run()
.在代码运行的时候总会调用子类的run()
.这样我们就获得了继承的另外一个好处,多态。
要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和Python自带的数据类型,比如str、list、dict没什么两样:
a = list() # a是list类型
b = Animal() # b是Animal类型
c = Dog() # c是Dog类型
判断一个变量是否是某个类型可以用isinstance()判断:
>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
>>> isinstance(c, Dog)
True
a
,b
,c
都对于着list、Animal、Dog这三种类型但是:
>>> isinstance(c,Animal)
True
Dog
,c还是Animal
!Dog
是从Animal
继承下来的,当我们创建了一个Dog
的实例c时,我们认为c的数据类型是Dog
没错,但c同时也是Animal
也没错,Dog
本来就是Animal的一种!所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行:
>>> b = Animal()
>>> isinstance(b, Dog)
False
要理解多态的好处,我们编写一个函数
def run_twice(animal):
animal.run()
animal.run()
当我们传入Animal的实例时,run_twice()就打印出:
>>> def run_twice(Animal()):
Animal is running..
Animal is running..
当我们传入Dog的实例时,run_twice()就打印出:
>>> def run_twice(Dog()):
Dog is running..
Dog is running..
当我们传入Cat的实例时,run_twice()就打印出:
>>> def run_twice(Cat()):
Cat is running..
Cat is running..
如果我们再定义一个Tortoise类型,也从Animal派生:
class Tortoise(Animal):
def run(self):
print(‘Tortoise is running slowly...‘)
当我们调用run_twice()时,传入Tortoise的实例:
>>> run_twice(Tortoise())
Tortoise is running slowly...
Tortoise is running slowly...
对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:
添加:
子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用,可以使用 [父类名.父类成员] 的格式来调用父类成员,也可以使用super().父类成员的格式来调用。
class Animal(object):
def run(self):
print("Animal is runnung...")
class Dog(Animal):
def run(self):
print(‘Dog is running...‘)
class Cat(Animal):
def run(self):
super().run()
print(‘Cat is running...‘)
我们正确的做法是采用多重继承,首先主要层次任然安装哺乳动物,和鸟类分:
class Animal(object):
pass
# 大类:
class Mammal(Animal):
pass
class Bird(Animal):
pass
# 各种动物:
class Dog(Mammal):
pass
class Bat(Mammal):
pass
class Parrot(Bird):
pass
class Ostrich(Bird):
pass
然后,我们在给动物加上Runnable和Flyable的功能,只需要先定义好Runnable和Flyable的类:
class Runnable(object):
def run(self):
print(‘Running...‘)
class Flyable(object):
def fly(self):
print(‘Flying...‘)
-对于需要Runnable功能的动物,就多继承一个Runnable,例如Dog:
class Dog(Mammal, Runnable):
pass
对于需要Flyable功能的动物,就多继承一个Flyable,例如Bat:
class Bat(Mammal, Flyable):
pass
通过多重继承,一个子类就可以同时获得多个父类的所有功能。
标签:lis 设置 ref 开放 构造函数 ima 方便 父类 false
原文地址:https://www.cnblogs.com/yangaoteng666/p/9228177.html