本节开始,我们将讨论面向对象编程的三大特征:封装、继承和多态。下面,我们将由简至难,依次讨论封装、继承、多态。
class A:
"""用私有属性和私有方法封装属性和方法"""
__dd = 300
def __init__(self):
# 创建私有属性,此属性在类外无法访问
self.__e = 100
@staticmethod
# 私有方法
def __en():
print('私有方法__en被调用!')
@classmethod
def get__dd(cls):
print("私有的类变量__dd:{}".format(cls.__dd))
def info(self):
print('A的实例方法info访问私有属性__e:', self.__e)
# 调用私有方法
self.__en()
if __name__ == "__main__":
a = A()
a.info()
a.__class__.get__dd()
# print(a.__e) #AttributeError: 'A' object has no attribute '__e'
# print(a.__en()) #AttributeError: 'A' object has no attribute '_en'
# 创建新变量(属性)
a.__e = 'hello'
print(a.__e)
print(a.__dict__)
运行结果:
1. 单继承
class 类名(基类名):
语句块
class Human:
"""此类用来描述人类的共同行为"""
@staticmethod
def say(what):
print('说:', what)
@staticmethod
def walk(distance):
print('走了', distance, '公里')
class Student(Human):
"""描述学生的共同行为"""
@staticmethod
def study(subject):
print('学习', subject)
class Teacher(Student):
@staticmethod
def teach(content):
print('正在教', content)
if __name__ == "__main__":
h1 = Human()
h1.say('Today is a good day.')
h1.walk(5)
print("#########################")
s1 = Student()
s1.say('How are you?')
s1.walk(5)
s1.study('Python')
print("#########################")
t1 = Teacher()
t1.say('I am a teacher.')
t1.walk(3)
t1.teach('讲解继承派生')
t1.study('滑冰')
运行结果:
2. 覆盖 override
class Human:
def __init__(self, n, a):
self.name = n
self.age = a
def info(self):
print('name:', self.name)
print('age:', self.age)
class Student(Human):
def __init__(self, n, a, s):
# 显示调用父类的初始化方法
super().__init__(n, a)
self.score = s
def info(self):
"""# 覆盖,子类只负责干子类的事情"""
super().info()
print('score:', self.score)
if __name__ == "__main__":
h1 = Human('Alex', 22)
h1.info()
s1 = Student('Thomas', 25, 99)
s1.info()
示例2:
class A:
def work(self):
print('A.work被调用!')
class B(A):
"""用super构造函数来间接调用父类的覆盖版本的方法"""
def work(self):
print('B.work被调用!')
def super_work(self):
"""此方法先调用一下子类的方法,再调用一下父类的方法"""
self.work()
# super().work() #调用父类的work,不能在方法外调用
# super(B,self).work()
super(__class__, self).work()
if __name__ == "__main__":
a = A()
a.work()
print("###################")
b = B()
b.work()
# 方法外部,使用super()函数调用B的父类A的work方法
print("###################")
super(B, b).work()
print("###################")
b.super_work()
示例2运行结果:
2. 多继承 multiple inheritance
class A:
def m(self):
print('A.m()')
class B:
def m(self):
print('B.m()')
class C:
def m(self):
print('C.m()')
class D(A, B, C):
def m(self):
super(A, self).m()
super(B, self).m()
super().m()
print('D.m()')
if __name__ == "__mian__":
d = D()
d.m()
print(D.__mro__)
运行结果:
结果分析:super()函数根据MRO顺序来查找方法
类D同时继承自类A,B, C,且这些类中都有方法m,在调用super时,方法的查找顺序是按照D.__mro__属性指定的顺序;在D.m()中首先调用的是super(A, self).m(),A的上一个是B,因此首先打印B.m();同理,super(B, self).m(),B的上一个是C,因此打印C.m()。
3. 用于类的函数:issubclass(cls, class_or_tuple)
class Shape:
def draw(self):
print('Shape的draw()被调用')
class Point(Shape):
def draw(self):
print('正在画一个点')
class Circle(Point):
def draw(self):
print('正在画一个圆')
def my_draw(s):
"""示意多态的使用"""
# s.draw调用谁是在运行时由s的类动态决定
s.draw()
if __name__ == "__main__":
my_draw(Shape())
my_draw(Point())
my_draw(Circle())
运行结果: