📜  Python中的面向对象编程 | Set 3(继承、对象实例、issubclass 和 super)

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

Python中的面向对象编程 | Set 3(继承、对象实例、issubclass 和 super)

我们已经讨论了以下关于Python中的面向对象编程的主题

  • Python中的面向对象编程|第一组
  • Python中的面向对象编程| Set 2(数据隐藏和对象打印)

本文介绍了继承。

面向对象编程的主要优点之一是重用。继承是实现这一目标的机制之一。在继承中,一个类(通常称为超类)被另一个类(通常称为子类)继承。子类为超类添加了一些属性。

下面是一个示例Python程序,展示了如何在Python中实现继承。

# 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 employee
    def isEmployee(self):
        return False
  
  
# Inherited or Sub class (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())
输出:
('Geek1', False)
('Geek2', True)

如何检查一个类是否是另一个类的子类?
Python提供了一个函数issubclass() ,它直接告诉我们一个类是否是另一个类的子类。

# Python example to check if a class is
# subclass of another
  
class Base(object):
    pass   # Empty Class
  
class Derived(Base):
    pass   # Empty Class
  
# Driver Code
print(issubclass(Derived, Base))
print(issubclass(Base, Derived))
  
d = Derived()
b = Base()
  
# b is not an instance of Derived
print(isinstance(b, Derived))
  
# But d is an instance of Base
print(isinstance(d, Base))
输出:
True
False
False
True

什么是对象类?
与Java Object 类一样,在Python (从版本 3.x 开始)中,object 是所有类的根。

在Python 3.x 中,“class Test(object)”和“class Test”是相同的。
在Python 2.x 中,“class Test(object)”创建了一个以 object 作为父类的类(称为新样式类),“class Test”创建了旧样式类(没有对象父类)。有关更多详细信息,请参阅此。

Python是否支持多重继承?
与Java和 C++ 不同, Python支持多重继承。我们将所有父类指定为括号中的逗号分隔列表。

# Python example to show 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')

如何访问子类中的父成员?

  1. 使用父类名
    # Python example to show that base
    # class members can be accessed in
    # derived class using base class name
    class Base(object):
      
        # Constructor
        def __init__(self, x):
            self.x = x    
      
    class Derived(Base):
      
        # Constructor
        def __init__(self, x, y):
            Base.x = x 
            self.y = y
      
        def printXY(self):
           
           # print(self.x, self.y) will also work
           print(Base.x, self.y)
      
      
    # Driver Code
    d = Derived(10, 20)
    d.printXY()
    
    输出:
    (10, 20)
    
  2. 使用超级()
    我们还可以使用 super 访问父类成员。
    # Python example to show that base
    # class members can be accessed in
    # derived class using super()
    class Base(object):
      
        # Constructor
        def __init__(self, x):
            self.x = x    
      
    class Derived(Base):
      
        # Constructor
        def __init__(self, x, y):
              
            ''' In Python 3.x, "super().__init__(name)"
                also works''' 
            super(Derived, self).__init__(x)
            self.y = y
      
        def printXY(self):
      
           # Note that Base.x won't work here
           # because super() is used in constructor
           print(self.x, self.y)
      
      
    # Driver Code
    d = Derived(10, 20)
    d.printXY()
    
    输出:
    (10, 20)
    

    请注意,上述两种方法并不完全相同。在下一篇关于继承的文章中,我们将介绍以下主题。
    1) 超级如何运作?通过父类名和父类名访问成员有何不同?
    2) 如何在Python中处理 Diamond 问题?

    锻炼:
    预测以下Python程序的输出

    1. class X(object):
          def __init__(self, a):
              self.num = a
          def doubleup(self):
              self.num *= 2
        
      class Y(X):
          def __init__(self, a):
              X.__init__(self, a)
          def tripleup(self):
              self.num *= 3
        
      obj = Y(4)
      print(obj.num)
        
      obj.doubleup()
      print(obj.num)
        
      obj.tripleup()
      print(obj.num)
      
      输出:
      4
      8
      24
      
    2. # Base or Super class
      class Person(object):
          def __init__(self, name):
              self.name = name
                
          def getName(self):
              return self.name
            
          def isEmployee(self):
              return False
        
      # Inherited or Subclass (Note Person in bracket)
      class Employee(Person):
          def __init__(self, name, eid):
        
              ''' In Python 3.0+, "super().__init__(name)"
                  also works''' 
              super(Employee, self).__init__(name)
              self.empID = eid
                
          def isEmployee(self):
              return True
                
          def getID(self):
              return self.empID
        
      # Driver code
      emp = Employee("Geek1", "E101") 
      print(emp.getName(), emp.isEmployee(), emp.getID())
      
      输出:
      ('Geek1', True, 'E101')