Python面向对象-类的继承
继承和多态
在面向对象程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass)或派生类,而被继承的class称为基类(Base class)、父类或超类(Super class)。
比如我们已经编写了一个名为Animal
的class,有一个run()
方法:
class Animal:
def run(self):
print('Animal is runing...')
当我们需要编写Dog
和Cat
类时,就可以直接从Animal
类继承:
class Dog(Animal):
pass
class Cat(Animal):
pass
对于Dog
和Cat
来说,Animal
就是它们的父类。对于Animal
来说,Dog
和Cat
就是它的子类。
继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial
实现了run()
方法,因此,Dog
和Cat
作为它的子类,什么事也没干,就自动拥有了run()
方法:
dog = Dog()
dog.run()
cat = Cat()
cat.run()
当然,也可以对子类增加一些方法,比如Dog类:
calss Dog:
def eat(self):
print('the dog is eating')
继承的第二个好处需要我们对代码做一点改进。你看到了,无论是Dog
还是Cat
,它们run()
的时候,显示的都是Animal is running...
,符合逻辑的做法是分别显示Dog is running...
和Cat is running...
,因此,对Dog
和Cat
类改进如下:
class Dog(Animal):
def run(self):
print('Dog is running...')
class Cat(Animal):
def run(self):
print('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()
判断:
由于Dog
是Animal
的子类,所以创建一个Dog
的实例c
时,我们认为c
的数据类型是Dog
,同时c
也是Animal
。
所以:
所以,在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行:
子类继承父类构造函数
如果重写了_init_ 时,实例化子类,就不会调用父类已经定义的 _init_,语法格式如下:
class Father(object):
def __init__(self, name):
self.name = name
print("name: %s" % self.name)
def getName(self):
return 'Father ' + self.name
class Son(Father):
def __init__(self, name):
print("hi")
self.name = name
def getName(self):
return 'Son ' + self.name
son = Son('Python')
print(son.getName())
如果在子类中需要父类的构造方法就需要显式地调用父类的构造方法,或者不重写父类的构造方法。
1.子类不重写 _init_,实例化子类时,会自动调用父类定义的 _init_。
class Father(object):
def __init__(self, name):
self.name=name
print ( "name: %s" % self.name )
def getName(self):
return 'Father ' + self.name
class Son(Father):
def getName(self):
return 'Son '+self.name
son=Son('runoob')
print ( son.getName() )
如果重写了 _init_ 时,要继承父类的构造方法,需要使用 super 关键字:
# 第一种方法
super(子类, self).__init__(参数1, 参数2...)
# 第二种方法
父类.__init__(self, 参数1, 参数2...)
class Father(object):
def __init__(self, name):
self.name = name
print("name: %s" % self.name)
def getName(self):
return 'Father ' + self.name
class Son(Father):
def __init__(self, name):
super(Son, self).__init__(name)
# Father.__init__(self, name)
print("hi")
self.name = name
def getName(self):
return 'Son ' + self.name
son = Son('Python')
print(son.getName())
本文来自博客园,作者:雨-铃,原文链接:https://www.cnblogs.com/yuling25/p/class-extend.html