单重继承与多态
class Car(object):
def __init__(self, name, size=10):
self.name = name
# 私有属性
self.__size = size
def run(self):
print(self.name, "car is running")
class GasCar(Car):
def run(self):
print(self.name, self.__size, "gas is burning")
class OilCar(Car):
def run(self):
print(self.name, self.__size, "oil is burning")
def run_twice(here):
here.run()
here.run()
gas_car = GasCar("奔驰")
oil_car = OilCar("路虎")
gas_car.run()
oil_car.run()
# 多态测试
print(isinstance(gas_car, Car))
print(isinstance(oil_car, Car))
run_twice(gas_car)
总结:子类对象确实拥有了父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问到的,只是拥有。
多态:多态是通过子类重写父类的方法中体现出来的。对于C++,要想实现方法的重写,需要使用virtual关键字,以实现动绑定。Python中多态的实现,便是通过virtual进行实现的。多态体现的继承体系中的多态。在非继承体系中,python也有“”“feel-like object”类型。这种操作能够实现的原因便是python是一种动态语言类型。这种特性,就像是函数之间的调用,不管你只要有该方法,不管是哪个类型中的,都能够实现调用。
class F1:
pass
# 假设,S1是我们的正统类,它继承于根正苗红的F1,是我们的正统类
class S1(F1):
def show(self):
print('S1.show')
# S2是路人甲,是个歪瓜裂枣,但是他自己也有一个叫show的方法。
class S2:
def show(self):
print('S2.show')
# 在Java或C#中定义函数参数时,必须指定参数的类型,也即是说,我们如果用
# Java写下面的Func,需要告知,obj是F1类还是其他什么东西。
# 如果限定了F1,那么S2是不可以被采纳的。
# 然而,在Python中,一切都是Obj,它不care你到底是什么类,直接塞进去就可以
def Func(obj):
"""Func函数需要接收一个F1类型或者F1子类的类型"""
obj.show()
s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show
s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
多重继承
#!/usr/bin/python3
# 类定义
class People:
# 定义基本属性
name = ''
age = 0
# 定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
# 定义构造方法
def __init__(self, n, a, w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" % (self.name, self.age))
# 单继承示例
class Student(People):
grade = ''
def __init__(self, n, a, w, g):
# 调用父类的构函
People.__init__(self, n, a, w)
self.grade = g
# 覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级" % (self.name, self.age, self.grade))
# 另一个类,多重继承之前的准备
class Speaker:
topic = ''
name = ''
def __init__(self, n, t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s" % (self.name, self.topic))
# 多重继承
class Sample(Speaker, Student):
a = ''
def __init__(self, name, age, weight, grade, topic):
Student.__init__(self, name, age, weight, grade)
Speaker.__init__(self, name, topic)
test = Sample("胡歌", 25, 80, 4, "Python")
# 方法名同,默认调用的是在括号中排前地父类的方法
test.speak()
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。