Fork me on GitHub

【基础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 方法都可以。

  

  

 

 

  

posted @ 2021-12-28 22:36  橘子偏爱橙子  阅读(65)  评论(0编辑  收藏  举报