【基础13】【自学笔记】python类的封装、继承、多态
一、类的封装(Encapsulation)
定义:封装是指将数据与具体操作的实现代码放在某个对象内部,使这些代码的实现细节不被外界发现,外界只能通过接口使用该对象,而不能通过任何形式修改对象内部实现
示例:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
xh = Person(name="小红", age=27)
if xh.age >= 18:
print(f"{xh.name}已经是成年人了")
else:
print(f"{xh.name}还是未年人")
如果想判断小明是不是成年人,需要使用 xh.age 来与 18 比较。年龄对于女生非常隐私的。如果不想年龄被人随意就获取,可以在 age 前加两个下划线,将其变成一个私有变量。外界就无法随随便便就知道某个人年龄啦
这时候,就该 封装 出场啦。
我可以定义一个用于专门判断一个人是否成年人的函数,对 self.__age 这个属性进行封装。
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
def is_adult(self):
return self.__age >= 18
xh = Person(name="小红", age=27)
xh.is_adult()
二、类的继承(Inheritance)
定义:被继承的类称为基类(也叫做父类),继承而得的类叫派生类(也叫子类),这种关系就像人类的父子关系。
继承的语法结构是
class 子类(父类):
1. 单继承
举个例子:下面的代码中。先是定义了一个 People 类,里面有一个 speak 方法。然后再定义一个 Student 类,并继承自 People 类。
# 父类定义
class People:
def __init__(self, name, age, weight):
self.name = name
self.age = age
def speak(self):
print(f"{self.name} 说: 我{self.age}岁。")
# 单继承示例
class Student(People):
def __init__(self, name, age, weight, grade):
# 调用父类的实例化方法
People.__init__(self, name, age, weight)
self.grade = grade
由于继承的机制,Student 实例会拥有 People 类所有属性和方法,比如下边我可以直接调用 People 类的 speak 方法。
>>> xm = Student(name="小明", age=10, weight=50, grade="三年级") >>> xm.speak() 小明 说: 我 10 岁。
重写: 覆盖父类的 speak 方法。
# 单继承示例
class Student(People):
def __init__(self, name, age, weight, grade):
# 调用父类的实例化方法
People.__init__(self, name, age, weight)
self.grade = grade
# 重写父类的speak方法
def speak(self):
print(f"{self.name} 说: 我{self.age}岁了,我在读{self.grade}")
此时,再调用的话,就会调用自己的方法了
>>> xm = Student(name="小明", age=10, weight=50, grade="三年级") >>> xm.speak() 小明 说: 我10岁了,我在读三年级
2. 多继承
Python 还支持多继承,可以继承自多个类。
class 子类(父类1, 父类2, 父类3...):
有如下代码,定义了 7 个类
class D:pass
class C(D):pass
class B(C):
def show(self):
print("i am B")
class G:pass
class F(G):pass
class E(F):
def show(self):
print("i am E")
class A(B, E):pass
它们的继承关系是
>>> a = A() >>> a.show() i am B
在类A中,没有show()这个方法,于是它只能去它的父类里查找,它首先在B类中找,结果找到了,于是直接执行B类的show()方法。可见,在A的定义中,继承参数的书写有先后顺序,写在前面的被优先继承。
3. 继承顺序
那如果B没有show方法,而是D有呢?
class D:
def show(self):
print("i am D")
class C(D):pass
class B(C):pass
class G:pass
class F(G):pass
class E(F):
def show(self):
print("i am E")
class A(B, E):pass
执行结果是
>>> a = A() >>> a.show() i am D
由此可见,多继承的顺序使用的是从左向右再深度优先的原则。
三、类的多态(Polymorphism)
多态,是指在同一类型下的不同形态。
class People:
def speak(self):
pass
class American(People):
def speak(self):
print("Hello, boys")
class Chinese(People):
def speak(self):
print("你好,老铁")
p1 = American()
p2 = Chinese()
American 和 Chinese 都继承了 People 类,但他们在 speak() 函数下,却有不同的形态表现。American 说英文,Chinese 说汉语。
倘若现在有一个 do_speak 函数
def do_speak(people):
people.speak()
do_speak(p1)
do_speak(p2)
那么无论传入的 American 实例还是 Chinese 实例,只要他有实现 speak 方法都可以。