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

58 篇文章 0 订阅
25 篇文章 0 订阅

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__则是在实例已经创建后被调用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值