Python面向对象-类的继承

继承是面向对象的重要特性之一,作为面向对象的Python,接下来让我们探讨一下Python的继承机制

为什么继承?

减少代码的重复性,提高代码的复用性

能继承什么?
  • 公有属性
  • 公有方法
怎么继承?

了解了python中类的基础知识后,让我们看一下神奇的继承机制
python中继承的基本格式如下:

#父类
class superClassName:
    pass

#子类
class subClassName(superClassName):
    pass

子类需要继承父类的构造方法时,必须显示的调用,并传递参数 self

# -*- coding: utf-8 -*-
class People:
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def getName(self):
        return self.__name

    def getAge(self):
        return self.__age

class Xiaonan(People):
    
    def __init__(self, name, age):
        #注意要显示调用父类构造方法,并传递参数self
        People.__init__(self, name, age)

xn = Xiaonan('xioaonan', 20)
print xn.getName()  #xiaonan
print xn.getAge()   #20

需要注意的有以下几点:

  1. 如果父类和子类都重新定义了构造方法__init()__,子类实例化时,子类的构造方法不会自动调用父类的构造方法,必须在子类中显示调用。
  2. 如果需要在子类中调用父类的方法,需要以 "父类名.方法" 这种方式调用,以这种方式调用的时候,注意要传递self参数过去。
# -*- coding: utf-8 -*-
class People:

    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def getName(self):
        return self.__name

    def getAge(self):
        return self.__age

    def Miss(self):
        print "I miss you in People"

class Xiaonan(People):
    
    def __init__(self, name, age):
        People.__init__(self, name, age)

    def InSub(self):
        People.Miss()

xn = Xiaonan('xioaonan', 20)
print xn.getName()
print xn.getAge()
xn.InSub()

运行结果为:

xioaonan
20
Traceback (most recent call last):
  File "test.py", line 28, in 
    xn.InSub()
  File "test.py", line 23, in InSub
    People.Miss()
TypeError: unbound method Miss() must be called with People instance as first argument (got nothing instead)
  1. 子类继承了父类所有的公有属性和方法,可以在子类中通过父类名来调用,而对于私有的属性和方法,子类是不进行继承的,因此在子类中是无法通过父类名来访问的。
# -*- coding: utf-8 -*-
class People:

    height = 170
    __money = 10
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def getName(self):
        return self.__name

    def getAge(self):
        return self.__age

    def Miss(self):
        print "I miss you in People"
    
    def __say(self):
        print "I can say in People"

class Xiaonan(People):
    
    def __init__(self, name, age):
        People.__init__(self, name, age)

    def InSub(self):
        print People.height
        People.Miss(self)
        print People.__money
        # People.__say(self)

xn = Xiaonan('xioaonan', 20)
print xn.getName()
print xn.getAge()
xn.InSub()

运行结果为:

xioaonan
20
170
I miss you in People
Traceback (most recent call last):
  File "test.py", line 37, in 
    xn.InSub()
  File "test.py", line 31, in InSub
    print People.__money
AttributeError: class People has no attribute '_Xiaonan__money'

print People.__money 这一行注释,下面一行打开时,同样的报错类型:

Traceback (most recent call last):
  File "ss1.py", line 37, in 
    xn.InSub()
  File "ss1.py", line 32, in InSub
    People.__say(self)
AttributeError: class People has no attribute '_Xiaonan__say'

python 支持多重继承

# -*- coding: utf-8 -*-
class People:
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def getName(self):
        return self.__name

    def getAge(self):
        return self.__age

class Student:
    
    def __init__(self, className, sno):
        self.className = className
        self.sno = sno
    
    def getClass(self):
        return self.className
        
    def getSno(self):
        return self.sno
    
class Xiaonan(People, Student):
    
    def __init__(self, name, age, className, sno):
        People.__init__(self, name, age)
        Student. __init__(self, className, sno)
        self.money = 100

xn = Xiaonan('xioaonan', 20, '软件班', 201158761)
print xn.getName()  #xiaonan
print xn.getSno()   #201158761
print xn.money      #100

多重继承始终以第一个父类中为中心:

  1. 当子类中未申明构造方法时,将自动调用第一个父类的构造方法
# -*- coding: utf-8 -*-
class People:
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def getName(self):
        return self.__name

    def getAge(self):
        return self.__age

    def eat(self):
        print 'I am having lunch'

class Student:
    
    def __init__(self, className, sno):
        self.className = className
        self.sno = sno
    
    def getClass(self):
        return self.className
        
    def getSno(self):
        return self.sno

    def eat(self):
        print 'I am having dinner'
    
class Xiaonan(People, Student):

    money = 100
    
xn = Xiaonan('xioaonan', 20)
print xn.getName()
print xn.getClass()

运行结果:

xioaonan
Traceback (most recent call last):
  File "test.py", line 38, in 
    print xn.getClass()
  File "test.py", line 24, in getClass
    return self.className
AttributeError: Xiaonan instance has no attribute 'className'

不难看出,的确调用的是第一个父类的构造方法

  1. 若多个父类中有含有同名的方法时,通过子类的实例化对象调用该方法,则调用的是第一个父类的该方法
# -*- coding: utf-8 -*-
class People:
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def getName(self):
        return self.__name

    def getAge(self):
        return self.__age

    def eat(self):
        print 'I am having lunch'

class Student:
    
    def __init__(self, className, sno):
        self.className = className
        self.sno = sno
    
    def getClass(self):
        return self.className
        
    def getSno(self):
        return self.sno

    def eat(self):
        print 'I am having dinner'
    
class Xiaonan(People, Student):

    money = 100

xn = Xiaonan('xioaonan', 20)
print xn.eat()

运行结果为

I am having lunch
None

你可能感兴趣的:(Python面向对象-类的继承)