29.从入门到精通:Python3 面向对象继承 多继承 方法重写 类属性与方法

简介: 29.从入门到精通:Python3 面向对象继承 多继承 方法重写 类属性与方法

继承

在面向对象编程中,继承是指通过继承现有类的属性和方法来创建新类的过程。新类称为子类(或派生类),现有类称为父类(或基类)。

  • 继承可以提高代码的重用性和可扩展性,减少代码的重复。子类可以继承父类的属性和方法,还可以添加自己的属性和方法,或者重写父类的方法。

在 Python 中,继承可以通过在类定义中指定父类来实现。例如:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
def <span class="hljs-title function_">say_hello</span>(self):
    <span class="hljs-title function_">print</span>(<span class="hljs-string">"Hello, my name is {} and I am {} years old."</span>.<span class="hljs-title function_">format</span>(self.<span class="hljs-property">name</span>, self.<span class="hljs-property">age</span>))
class Student(Person):
    def init(self, name, age, student_id):
        Person.init(self, name, age)
        self.student_id = student_id
def <span class="hljs-title function_">say_hello</span>(self):
    <span class="hljs-title class_">Person</span>.<span class="hljs-title function_">say_hello</span>(self)
    <span class="hljs-title function_">print</span>(<span class="hljs-string">"My student ID is {}."</span>.<span class="hljs-title function_">format</span>(self.<span class="hljs-property">student_id</span>))

在这个示例中,我们定义了一个名为 Person 的父类和一个名为 Student 的子类。子类 Student 继承了父类 Person的属性和方法,并添加了自己的属性和方法。 在子类中,我们可以使用 super() 函数来调用父类的方法。例如,在 Student 类的 init() 方法中,我们调用了父类 Person 的 init() 方法来初始化对象的属性。 我们还重写了父类 Person 的 say_hello() 方法,并在子类 Student 的 say_hello() 方法中调用了父类的say_hello() 方法,并添加了自己的输出。

下面是一个使用 Student 类的示例:

student = Student('John', 20, '123456')
student.say_hello()

在这个示例中,我们创建了一个名为 student 的 Student 对象,并调用了对象的 say_hello() 方法。由于Student 类继承了 Person 类的 say_hello() 方法,因此在调用子类的 say_hello() 方法时,父类的say_hello() 方法也会被调用。 希望这可以帮助您了解在 Python 中如何实现继承


多继承

多继承是指一个类可以同时继承多个父类的特性。在 Python 中,多继承可以通过在类定义时同时指定多个父类来实现。例如:

class A:
    def method_a(self):
        print("This is method A.")
class B:
    def method_b(self):
        print("This is method B.")
class C(A, B):
    def method_c(self):
        print("This is method C.")
c = C()
c.method_a()  # 输出:This is method A.
c.method_b()  # 输出:This is method B.
c.method_c()  # 输出:This is method C.

在上面的例子中,我们定义了三个类 A、B 和 C。类 A 和 B 分别定义了一个方法 method_a 和 method_b,类 C继承了类 A 和类 B,并且定义了一个方法 method_c。通过实例化类 C,我们可以调用所有三个方法

  • 需要注意的是,多继承可能会导致方法重名的问题。如果多个父类中都定义了同名的方法,那么在子类中调用该方法时,Python会按照一定的顺序搜索父类,直到找到第一个定义该方法的父类为止。

这个搜索顺序称为方法解析顺序(Method Resolution Order,简称 MRO),可以通过类的 mro 属性来查看。例如:

class A:
    def method(self):
        print("This is method A.")
class B:
    def method(self):
        print("This is method B.")
class C(A, B):
    pass
class D(B, A):
    pass
print(C.__mro__)  # 输出:(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(D.__mro__)  # 输出:(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)

在上面的例子中,我们定义了四个类 A、B、C 和 D。类 A 和 B 分别定义了一个方法 method,类 C 继承了类 A 和类 B,类D 继承了类 B 和类 A。通过查看类的 mro 属性,我们可以看到方法解析顺序是怎样的。在类 C 中调用 method 方法时,由于 A 在 B 前面,所以会优先调用 A 中的 method 方法。在类 D 中调用 method 方法时,由于 B 在 A 前面,所以会优先调用 B 中的 method 方法。


方法重写

在面向对象编程中,方法重写是指在子类中重新定义一个与父类中同名的方法。通过方法重写,子类可以改变继承自父类的方法的行为,从而实现自己的逻辑。方法重写也称为方法覆盖或方法复写。

在 Python 中,方法重写可以通过在子类中定义一个与父类中同名的方法来实现。例如:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def say_hello(self):
        print("Hello, my name is {} and I am {} years old.".format(self.name, self.age))
class Student(Person):
    def say_hello(self):
        print("Hello, my name is {} and I am a student.".format(self.name))

类属性与方法

类属性和类方法是指属于整个类而不是类的实例的属性和方法。类属性和类方法可以通过类名直接访问,也可以通过类的实例访问。以下是一个示例:

class Person:
    # 类属性
    species = "Homo sapiens"
<span class="hljs-comment"># 实例属性</span>
def <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, name, age</span>):
    self.name = name
    self.age = age
<span class="hljs-comment"># 实例方法</span>
def <span class="hljs-title function_">say_hello</span>(<span class="hljs-params">self</span>):
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Hello, my name is <span class="hljs-subst">{self.name}</span> and I am <span class="hljs-subst">{self.age}</span> years old."</span>)
<span class="hljs-comment"># 类方法</span>
@classmethod
def <span class="hljs-title function_">get_species</span>(<span class="hljs-params">cls</span>):
    <span class="hljs-built_in">print</span>(<span class="hljs-string">f"This is a {cls.species}."</span>)
person = Person("Alice", 25)
person.say_hello()  # 输出:Hello, my name is Alice and I am 25 years old.
Person.get_species()  # 输出:This is a Homo sapiens.

在上面的示例中,我们定义了一个 Person 类,包含了一个类属性 species、一个实例属性 name 和 age、一个实例方法 say_hello 和一个类方法 get_species。类属性和类方法都是通过在方法或属性前面加上 @classmethod装饰器来定义的。

类属性是属于整个类的属性,可以通过类名直接访问。在上面的示例中,我们通过 Person.species 来访问类属性 species。

类方法是属于整个类的方法,可以通过类名直接调用。在上面的示例中,我们通过 Person.get_species() 来调用类方法 get_species。需要注意的是,类方法的第一个参数通常是 cls,表示类本身。


相关文章
|
3天前
|
Python
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
Python从入门到精通:深入学习面向对象编程——2.1.2继承、封装和多态的概念
|
3天前
|
存储 索引 Python
Python从入门到精通——1.3.1练习编写简单程序
Python从入门到精通——1.3.1练习编写简单程序
|
4天前
|
开发框架 前端开发 数据库
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
|
4天前
|
数据采集 数据可视化 数据处理
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
Python从入门到精通的文章3.3.1 深入学习Python库和框架:数据处理与可视化的利器
|
4天前
|
Java 数据库连接 数据处理
Python从入门到精通:3.1.2多线程与多进程编程
Python从入门到精通:3.1.2多线程与多进程编程
|
4天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
4天前
|
人工智能 Python
【Python实用技能】建议收藏:自动化实现网页内容转PDF并保存的方法探索(含代码,亲测可用)
【Python实用技能】建议收藏:自动化实现网页内容转PDF并保存的方法探索(含代码,亲测可用)
24 0
|
4天前
|
Python
Python 一步一步教你用pyglet制作可播放音乐的扬声器类
Python 一步一步教你用pyglet制作可播放音乐的扬声器类
16 0
|
9天前
|
存储 关系型数据库 MySQL
Python搭建代理IP池实现存储IP的方法
Python搭建代理IP池实现存储IP的方法
|
9天前
|
Python
Python动态IP代理防止被封的方法
Python动态IP代理防止被封的方法