📜  Python中的继承

📅  最后修改于: 2022-05-13 01:55:06.353000             🧑  作者: Mango

Python中的继承

继承是一个类从另一个类派生或继承属性的能力。继承的好处是:

  1. 它很好地代表了现实世界的关系。
  2. 它提供了代码的可重用性。我们不必一次又一次地编写相同的代码。此外,它允许我们在不修改类的情况下向类添加更多功能。
  3. 它本质上是可传递的,这意味着如果类 B 继承自另一个类 A,那么 B 的所有子类将自动继承自类 A。

下面是一个简单的Python继承示例

Python3
# A Python program to demonstrate inheritance
  
# Base or Super class. Note object in bracket.
# (Generally, object is made ancestor of all classes)
# In Python 3.x "class Person" is
# equivalent to "class Person(object)"
class Person(object):
      
    # Constructor
    def __init__(self, name):
        self.name = name
  
    # To get name
    def getName(self):
        return self.name
  
    # To check if this person is an employee
    def isEmployee(self):
        return False
  
  
# Inherited or Subclass (Note Person in bracket)
class Employee(Person):
  
    # Here we return true
    def isEmployee(self):
        return True
  
# Driver code
emp = Person("Geek1")  # An Object of Person
print(emp.getName(), emp.isEmployee())
  
emp = Employee("Geek2") # An Object of Employee
print(emp.getName(), emp.isEmployee())


Python3
# Python code to demonstrate how parent constructors
# are called.
 
# parent class
class Person( object ):   
 
        # __init__ is known as the constructor        
        def __init__(self, name, idnumber):  
                self.name = name
                self.idnumber = idnumber
        def display(self):
                print(self.name)
                print(self.idnumber)
 
# child class
class Employee( Person ):          
        def __init__(self, name, idnumber, salary, post):
                self.salary = salary
                self.post = post
 
                # invoking the __init__ of the parent class
                Person.__init__(self, name, idnumber)
 
                 
# creation of an object variable or an instance
a = Employee('Rahul', 886012, 200000, "Intern")   
 
# calling a function of the class Person using its instance
a.display()


Python3
# Python program to demonstrate error if we
# forget to invoke __init__() of the parent.
 
class A:
      def __init__(self, n = 'Rahul'):
              self.name = n
class B(A):
      def __init__(self, roll):
              self.roll = roll
 
object = B(23)
print (object.name)


Python
# Python example to show the working of multiple
# inheritance
class Base1(object):
    def __init__(self):
        self.str1 = "Geek1"
        print("Base1")
 
class Base2(object):
    def __init__(self):
        self.str2 = "Geek2"       
        print("Base2")
 
class Derived(Base1, Base2):
    def __init__(self):
         
        # Calling constructors of Base1
        # and Base2 classes
        Base1.__init__(self)
        Base2.__init__(self)
        print("Derived")
         
    def printStrs(self):
        print(self.str1, self.str2)
        
 
ob = Derived()
ob.printStrs()


Python3
# A Python program to demonstrate inheritance
 
# Base or Super class. Note object in bracket.
# (Generally, object is made ancestor of all classes)
# In Python 3.x "class Person" is
# equivalent to "class Person(object)"
class Base(object):
     
    # Constructor
    def __init__(self, name):
        self.name = name
 
    # To get name
    def getName(self):
        return self.name
 
 
# Inherited or Sub class (Note Person in bracket)
class Child(Base):
     
    # Constructor
    def __init__(self, name, age):
        Base.__init__(self, name)
        self.age = age
 
    # To get name
    def getAge(self):
        return self.age
 
# Inherited or Sub class (Note Person in bracket)
class GrandChild(Child):
     
    # Constructor
    def __init__(self, name, age, address):
        Child.__init__(self, name, age)
        self.address = address
 
    # To get address
    def getAddress(self):
        return self.address       
 
# Driver code
g = GrandChild("Geek1", 23, "Noida") 
print(g.getName(), g.getAge(), g.getAddress())


Python3
# Python program to demonstrate private members
# of the parent class
class C(object):
       def __init__(self):
              self.c = 21
 
              # d is private instance variable
              self.__d = 42   
class D(C):
       def __init__(self):
              self.e = 84
              C.__init__(self)
object1 = D()
 
# produces an error as d is private instance variable
print(object1.d)


输出:
Geek1 False
Geek2 True

什么是对象类?
与Java Object 类一样,在Python (从版本 3.x 开始)中,object 是所有类的根。
在Python 3.x 中,“class Test(object)”和“class Test”是相同的。
在Python 2.x 中,“class Test(object)”创建了一个以 object 作为父类的类(称为新样式类),“class Test”创建了旧样式类(没有对象父类)。有关更多详细信息,请参阅此。
子类化(调用父类的构造函数)
子类需要识别哪个类是它的父类。这可以通过在子类的定义中提及父类名称来完成。
例如:类子类名(超类名)
_ _ _
_ _ _

Python3

# Python code to demonstrate how parent constructors
# are called.
 
# parent class
class Person( object ):   
 
        # __init__ is known as the constructor        
        def __init__(self, name, idnumber):  
                self.name = name
                self.idnumber = idnumber
        def display(self):
                print(self.name)
                print(self.idnumber)
 
# child class
class Employee( Person ):          
        def __init__(self, name, idnumber, salary, post):
                self.salary = salary
                self.post = post
 
                # invoking the __init__ of the parent class
                Person.__init__(self, name, idnumber)
 
                 
# creation of an object variable or an instance
a = Employee('Rahul', 886012, 200000, "Intern")   
 
# calling a function of the class Person using its instance
a.display()
输出:
Rahul
886012

'a' 是为 Person 类创建的实例。它调用被引用类的 __init__()。您可以在 Person 类的声明中看到“对象”。在Python中,每个类都继承自一个名为“object”的内置基本类。当我们创建对象变量或类的实例时,会调用构造函数,即类的“__init__”函数。
在 __init__() 中定义的变量被称为实例变量或对象。因此,'name' 和 'idnumber' 是 Person 类的对象。同样,'salary' 和 'post' 是 Employee 类的对象。由于 Employee 类继承自 Person 类,“name”和“idnumber”也是 Employee 类的对象。
如果您忘记调用父类的 __init__() ,则子类将无法使用其实例变量。
出于同样的原因,以下代码会产生错误。

Python3

# Python program to demonstrate error if we
# forget to invoke __init__() of the parent.
 
class A:
      def __init__(self, n = 'Rahul'):
              self.name = n
class B(A):
      def __init__(self, roll):
              self.roll = roll
 
object = B(23)
print (object.name)

输出 :

Traceback (most recent call last):
  File "/home/de4570cca20263ac2c4149f435dba22c.py", line 12, in 
    print (object.name)
AttributeError: 'B' object has no attribute 'name'

不同形式的继承:
1、单继承:当一个子类只继承一个父类时,称为单继承。我们在上面看到了一个例子。
2、多重继承:当一个子类从多个父类继承时,称为多重继承。

与Java不同, Python显示多重继承。

Python

# Python example to show the working of multiple
# inheritance
class Base1(object):
    def __init__(self):
        self.str1 = "Geek1"
        print("Base1")
 
class Base2(object):
    def __init__(self):
        self.str2 = "Geek2"       
        print("Base2")
 
class Derived(Base1, Base2):
    def __init__(self):
         
        # Calling constructors of Base1
        # and Base2 classes
        Base1.__init__(self)
        Base2.__init__(self)
        print("Derived")
         
    def printStrs(self):
        print(self.str1, self.str2)
        
 
ob = Derived()
ob.printStrs()
输出:
Base1
Base2
Derived
Geek1 Geek2

3. 多级继承:当我们有子孙关系时。

Python3

# A Python program to demonstrate inheritance
 
# Base or Super class. Note object in bracket.
# (Generally, object is made ancestor of all classes)
# In Python 3.x "class Person" is
# equivalent to "class Person(object)"
class Base(object):
     
    # Constructor
    def __init__(self, name):
        self.name = name
 
    # To get name
    def getName(self):
        return self.name
 
 
# Inherited or Sub class (Note Person in bracket)
class Child(Base):
     
    # Constructor
    def __init__(self, name, age):
        Base.__init__(self, name)
        self.age = age
 
    # To get name
    def getAge(self):
        return self.age
 
# Inherited or Sub class (Note Person in bracket)
class GrandChild(Child):
     
    # Constructor
    def __init__(self, name, age, address):
        Child.__init__(self, name, age)
        self.address = address
 
    # To get address
    def getAddress(self):
        return self.address       
 
# Driver code
g = GrandChild("Geek1", 23, "Noida") 
print(g.getName(), g.getAge(), g.getAddress())
输出:
Geek1 23 Noida

4. 层次继承多个派生类是从一个基类创建的。
5.混合继承:这种形式结合了一种以上的继承形式。基本上,它是一种以上继承类型的混合。
父类的私有成员
我们并不总是希望父类的实例变量被子类继承,即我们可以将父类的一些实例变量设为私有,子类无法使用这些变量。
我们可以通过在名称前添加双下划线来创建实例变量。例如,

Python3

# Python program to demonstrate private members
# of the parent class
class C(object):
       def __init__(self):
              self.c = 21
 
              # d is private instance variable
              self.__d = 42   
class D(C):
       def __init__(self):
              self.e = 84
              C.__init__(self)
object1 = D()
 
# produces an error as d is private instance variable
print(object1.d)                    

输出 :

File "/home/993bb61c3e76cda5bb67bd9ea05956a1.py", line 16, in 
    print (object1.d)                     
AttributeError: type object 'D' has no attribute 'd'

由于这些下划线将“d”设为私有,因此子类“D”无法使用它,因此出现错误。