Python 如何访问父类属性
在面向对象编程中,继承使我们能够创建新的类,该类继承现有类的属性和方法。这个强大的概念使得我们的程序具有代码重用性,模块性和可扩展性。在深入讨论如何访问父类属性之前,让我们简要复习一下继承的概念。在Python中,当一个类继承于另一个类时,它会继承父类中定义的所有属性和方法。这种机制允许我们创建特定的类,继承并扩展更通用的基类的功能。派生类也被称为子类,而被继承的类称为父类或基类。
示例
这是一个简单的示例,用于说明继承的概念 –
class Parent:
def __init__(self):
self.parent_attribute = "I'm from the parent class"
class Child(Parent):
def __init__(self):
super().__init__()
self.child_attribute = "I'm from the child class"
child = Child()
print(child.parent_attribute) # Accessing parent class attribute
print(child.child_attribute)
输出
I'm from the parent class
I'm from the child class
在这个例子中,我们有两个类:Parent和Child。Child类使用语法class Child(Parent)继承自Parent类。这意味着Child类继承了Parent类中定义的所有属性和方法。Child类还有自己的属性child_attribute。
访问Parent类属性
在Python中访问父类属性,可以使用点表示法和实例或类名。选择的方法取决于上下文和特定要求。让我们探讨不同的访问父类属性的方法:
使用实例
如果你有子类的实例,你可以直接通过实例访问父类的属性。实例保留了从父类继承的所有属性和方法,让你可以轻松访问它们。
示例
以下是一个例子
class Parent:
def __init__(self):
self.parent_attribute = "I'm from the parent class"
class Child(Parent):
def __init__(self):
super().__init__()
self.child_attribute = "I'm from the child class"
child = Child()
print(child.parent_attribute) # Accessing parent class attribute using instance
输出
I'm from the parent class
在这个例子中,child.parent_attribute访问了父类中定义的parent_attribute属性。通过通过实例访问属性,你可以检索与该属性关联的值。
使用类名
除了通过实例访问父类属性之外,您还可以使用子类名称来访问它们。当您没有可用的实例,但仍然希望直接访问父类属性时,这种方法非常有用。
例子
这是一个例子 −
class Parent:
parent_attribute = "I'm from the parent class"
class Child(Parent):
child_attribute = "I'm from the child class"
print(Child.parent_attribute) # Accessing parent class attribute using class name
输出
I'm from the parent class
在这种情况下,Child.parent_attribute访问了在父类中定义的parent_attribute。通过使用类名,您可以直接访问父类属性,而无需实例。
访问父类方法
继承不仅允许我们访问父类属性,还允许我们访问父类方法。当一个子类继承自一个父类时,它继承了父类中定义的所有方法。这意味着您可以在子类中使用实例或类名来调用这些方法。
示例
以下是一个例子 –
class Parent:
def parent_method(self):
print("This is a method from the parent class")
class Child(Parent):
def __init__(self):
super().__init__()
child = Child()
child.parent_method() # Accessing parent class method using instance
Child.parent_method() # Accessing parent class method using class name
输出
This is a method from the parent class
This is a method from the parent class
在这个例子中,子类继承了父类的parent_method方法。我们可以使用子类的实例(child.parent_method())或者直接使用类名(Child.parent_method())来调用这个方法。
覆盖父类属性
在某些情况下,你可能需要在子类中覆盖父类的属性。覆盖意味着为子类中的特定属性提供不同的值或行为。通过在子类中重新定义属性,你可以自定义其值,同时还可以使用之前讨论的技术访问父类属性。
例子:
这里是一个例子-
class Parent:
def __init__(self):
self.shared_attribute = "I'm from the parent class"
class Child(Parent):
def __init__(self):
super().__init__()
self.shared_attribute = "I'm from the child class"
child = Child()
print(child.shared_attribute) # Accessing overridden attribute
输出
I'm from the child class
在这个例子中,父类和子类都有一个名为shared_attribute的属性。然而,在子类中,我们重新定义了该属性并赋予了不同的值。当我们使用子类的实例(child.shared_attribute)访问该属性时,我们获取的是在子类中重新定义的覆盖值。
多重继承
Python支持多重继承,这意味着一个类可以从多个父类继承。在多重继承中,访问父类属性可能变得更加复杂。在这种情况下,您可能需要使用方法解析顺序(MRO)或super()函数来显式指定要访问的父类属性。
示例
下面是一个多重继承和访问父类属性的示例 −
class Parent1:
def __init__(self):
self.shared_attribute = "I'm from Parent1"
class Parent2:
def __init__(self):
self.shared_attribute = "I'm from Parent2"
class Child(Parent1, Parent2):
def __init__(self):
super().__init__()
child = Child()
print(child.shared_attribute) # Accessing parent class attribute in multiple inheritance
输出
I'm from Parent1
在这个例子中,Child类继承了Parent1和Parent2类。当我们创建Child类的一个实例并访问shared_attribute时,它获取的是在Parent1中定义的值。
受保护和私有属性
受保护的属性通常以单下划线(_)作为前缀,表示它们不应该在类外直接访问,但可以被子类访问。私有属性则通常以双下划线(__)作为前缀,表示只能在类内部访问。
示例
这里有一个例子 −
class Parent:
def __init__(self):
self._protected_attribute = "I'm a protected attribute"
self.__private_attribute = "I'm a private attribute"
class Child(Parent):
def __init__(self):
super().__init__()
child = Child()
print(child._protected_attribute) # Accessing protected attribute
print(child._Parent__private_attribute) # Accessing private attribute
输出
I'm a protected attribute
I'm a private attribute
在这个例子中,父类有一个受保护的属性_protected_attribute
和一个私有属性__private_attribute
。子类Child仍然可以访问这两个属性。然而,要访问私有属性需要使用名称修饰技术,格式为_ClassName__private_attribute
。
结论
继承是一个强大的功能,它允许我们创建类层次结构并在现有功能的基础上构建。通过访问父类属性,我们可以在程序中实现代码重用和模块化。
我们学到,访问父类属性可以使用实例或类名。通过实际例子,我们看到了如何使用子类的实例访问父类属性,以及如何使用类名直接访问它们。