【python】python面向对象之——继承

python面向对象之——继承

继承是面向对象编程中的一个重要概念。通过继承,一个对象可以基于另一个已存在的对象来创建,从而从已有的对象中获取属性和方法。被继承的对象称为父类(或基类、超类),继承自父类的对象称为子类(或派生类)。子类可以继承父类的属性和方法,并且可以添加自己的属性和方法。

通过继承,可以实现代码的复用,减少重复编写相同代码的工作。子类可以重写父类的方法,对其进行扩展或修改,从而实现多态性。

继承的一个主要目的是实现分类和封装,通过将共同的属性和方法抽象到父类中,可以更好地组织和管理代码。

一般来说,继承的关系是单向的,子类继承了父类的特性,但父类不知道子类的存在。但子类可以通过调用父类的方法来获取父类的特性。
Python中的继承代码格式如下:

class ParentClass:
    # 父类属性和方法

class ChildClass(ParentClass):
    # 子类属性和方法

父类和子类分别定义在类之间的括号中,用于指定父类。子类继承了父类的属性和方法。在子类中可以新增或覆盖父类的属性和方法。

例如,下面是一个使用继承的示例代码:

class Shape:
    def __init__(self, name):
        self.name = name
    
    def area(self):
        pass
    
class Rectangle(Shape):
    def __init__(self, name, width, height):
        super().__init__(name)
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, name, radius):
        super().__init__(name)
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius * self.radius

rect = Rectangle("长方形", 5, 10)
print(rect.area())  # 输出:50

circle = Circle("圆形", 2)
print(circle.area())  # 输出:12.56

在这个示例中,Shape是父类,RectangleCircle是子类。子类通过继承父类的属性和方法,并且可以覆盖父类的方法来实现具体的功能。

创建子类对象时是否会使用父类对象的new和init方法

在Python中,当你创建一个子类的对象时,Python会首先调用子类的__new__方法来创建一个新的实例。如果子类没有定义自己的__new__方法,那么它会调用其直接父类的__new__方法,这个过程会一直递归到基类(通常是object)为止。

接着,一旦新实例被创建,就会调用子类的__init__方法来初始化这个实例。如果子类没有定义自己的__init__方法,那么它的直接父类的__init__方法会被调用,这个过程同样会递归到基类。

然而,对于__init__方法,Python不会自动调用父类的构造器,除非子类显式地这样做。子类必须显式地调用父类的__init__方法,通常通过super()函数来实现。例如:

class Parent:
    def __init__(self):
        print("Parent's init called")

class Child(Parent):
    def __init__(self):
        super().__init__()  # 显式调用父类的init
        print("Child's init called")

在这个例子中,当你创建Child类的实例时,Parent类的__init__方法也会被调用,因为Child类中的__init__方法显式地调用了super().__init__()

如果你省略了super().__init__()调用,那么Parent类的__init__方法将不会被调用,这可能会导致一些问题,比如父类的初始化代码没有执行,或者父类期望的一些属性没有被正确设置。

当一个子类同时重写了__new____init__方法时,创建对象的过程如下:

  1. 首先,Python会调用子类的__new__方法来创建一个实例。如果子类没有定义__new__方法,则会调用父类的__new__方法。这个过程会一直继续到object基类为止。

  2. __new__方法应该返回一个新创建的实例。在__new__中,你可以进行一些额外的处理,如改变返回的实例类型或根据某些条件改变实例的行为。

  3. 接着,在__new__返回的实例上,Python会调用__init__方法。如果子类定义了自己的__init__方法,那么它会被调用;如果没有,就会调用父类的__init__方法,以此类推,直到到达object类。

  4. __init__不同,Python不会自动调用父类的__init__方法。你必须在子类的__init__方法中显式地调用它,通常使用super()函数。

例如:

class Base:
    def __new__(cls, *args, **kwargs):
        print("Base's __new__ called")
        return super().__new__(cls)
    
    def __init__(self):
        print("Base's __init__ called")

class Derived(Base):
    def __new__(cls, *args, **kwargs):
        print("Derived's __new__ called")
        return super().__new__(cls)
    
    def __init__(self):
        print("Derived's __init__ called")
        super().__init__()

# 创建Derived的实例
instance = Derived()

在这个例子中:

  • 创建Derived实例时,Derived__new__方法首先被调用,然后是Base__new__方法(通过super())。
  • 之后,Derived__init__方法被调用,它又显式地调用了Base__init__方法(同样通过super())。

因此,正确的调用顺序是:

  1. Derived__new__
  2. Base__new__
  3. Derived__init__
  4. Base__init__

注意,__new__是一个静态方法,而__init__是一个实例方法。这意味着__new__可以访问类对象,但不能访问实例(除非它已经被创建),而__init__则是在实例已经创建后被调用的。

相关推荐

  1. 【python】python面向对象——继承

    2024-07-20 06:22:05       18 阅读
  2. 面向对象继承

    2024-07-20 06:22:05       38 阅读
  3. 面向对象进阶-继承

    2024-07-20 06:22:05       53 阅读
  4. 面向对象继承方式(汇总)

    2024-07-20 06:22:05       59 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 06:22:05       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 06:22:05       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 06:22:05       45 阅读
  4. Python语言-面向对象

    2024-07-20 06:22:05       55 阅读

热门阅读

  1. HDFS和FDFS

    2024-07-20 06:22:05       19 阅读
  2. SQL Server语法大全

    2024-07-20 06:22:05       14 阅读
  3. 题解|2024暑期杭电多校01

    2024-07-20 06:22:05       20 阅读
  4. 【C语言ffmpeg】打开第一个视频

    2024-07-20 06:22:05       15 阅读
  5. 阿里云服务器 篇五:短链服务网站

    2024-07-20 06:22:05       15 阅读
  6. Held-Karp算法的C++代码

    2024-07-20 06:22:05       15 阅读
  7. 写一个简单的兼容GET/POST请求的登录接口

    2024-07-20 06:22:05       16 阅读