1.继承
效果:子类获得父类的全部功能。
使用方法:在定义类的括号中(object)
,object表示该类是从哪个类继承下来的,在object中填入需要继承的类(父类)的名字,就可以继承父类的全部功能了。
注意:如果没有合适的继承类,就使用object
类,这是所有类最终都会继承的类。
具体实践:
class Animal(object): def run(self): print('Animals is running...')class Dog(Animal): pass#新建一个实例dog = Dog()#这样子类Dog就可以使用父类的方法了dog.run()
Animals is running...
从上面可以看出:由于Animial有
run()
方法,Dog
作为它的子类,什么事也没干,就自动拥有了run()
方法。
2.多态
说白了:多态就是子类有个跟父类的一模一样方法名,方法内容不同。这样可以使得子类具有不同的方法实现。
对子类Dog()增加相同的方法run():
class Dog(Animal): def run(self): print('Dog is running...')
当子类和父类都存在相同的run()
方法时,子类的run()会
覆盖父类的run()方法,
在代码运行的时候,总是会调用子类的run()
。这样,我们就获得了继承的另一个好处:多态。
注意:多态首先是建立在继承的基础上的,先有继承才能有多态。
class Animal(object): def run(self): print('Animals is running...')class Dog(Animal): def run(self): print('Dog is running...')#新建一个实例dog = Dog()#这样子类Dog就可以使用父类的方法了dog.run()
Dog is running...
要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。
查看数据类型可以用type()方法和isinstance()方法
print type(())print type([])print type('aaa')print type(Animal())print type(Dog())
<type 'tuple'><type 'list'><type 'str'><class '__main__.Animal'><class '__main__.Dog'>
新建两个实例,判断其数据类型
class Animal(object): def run(self): print('Animals is running...')class Dog(Animal): def run(self): print('Dog is running...')a=Animal()b=Dog()#判断一个变量是否是某个类型可以用isinstance()判断print isinstance(a,Animal)print isinstance(b,Dog)print isinstance(b,Animal)
TrueTrueTrue
从运行结果可以看出,b的数据类型既是Dog,也是Animal。因为Dog
是Animal
的子类。
所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行。Dog
可以看成Animal
,但Animal
不可以看成Dog
。
说了这么多,多态有什么好处呢?
举个例子:编写一个函数,这个函数接受一个Animal
类型的变量
class Animal(object): def run(self): print('Animals is running...')class Dog(Animal): def run(self): print('Dog is running...')class Cat(Animal): def run(self): print('Cat is running...')def run_twice(animal): animal.run() animal.run()#传入Animalrun_twice(Animal())run_twice(Dog())run_twice(Cat())
运行结果:
Animals is running...Animals is running...Dog is running...Dog is running...Cat is running...Cat is running...
从上面结果可以看到:
对于一个变量,我们只需要知道它是Animal
类型,无需确切地知道它的子类型,就可以放心地调用run()
方法。而具体调用的run()
方法是作用在Animal
、Dog
、Cat
对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal
的子类时,只要确保run()
方法编写正确,不用管原来的代码是如何调用的。