首页 > 代码库 > 1.26 Python知识进阶 - 继承

1.26 Python知识进阶 - 继承

继承

  继承(Inheritance)是面向对象的程序设计中代码重要的主要方法。继承是允许使用现有类的功能,并在无需重新改写原来的类的情况下,对这些功能进行扩展。继承可以避免代码复制和相关的代码维护等问题。

  被继承的类称为“基类(Base Class)”、“父类” 或 “超类(Super Class)”,通过继承创建的新类称为“子类(Subclass)” 或 “派生类(Derived Class)”。

  声明格式:

    class 派生类(基类1,[基类2,...]):

      类体

  其中,派生类名后为所有基类的名称元组。如果在类定义中没有指定基类,则默认其基类为objec。object是所有对象的根基类。

  多个类的继承可以形成层次关系,通过类的方法mro()或类的属性__mro__可以输出其继承的层次关系。例如:

class A: pass


class B(A): pass


class C(B): pass


class D(A): pass


class E(B, D): pass


print(D.mro())
print(E.__mro__)

------------------line----------------------

[<class __main__.D>, <class __main__.A>, <class object>] (<class __main__.E>, <class __main__.B>, <class __main__.D>, <class __main__.A>, <class object>)

  声明派生类时,必须在其构造函数中调用基类的构造函数。调用格式:

    基类名.__init__(self,参数列表)

  定义一个Car类,再定义一个ElectricCar类,让其继承Car类属性和方法,示例代码:

class Car(object):
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0


    def get_descriptive_name(self):
        long_name = str(self.year) +   + self.make +   + self.model
        return long_name.title()


    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + "miles on it.")


    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can‘t roll back an odometer!")


    def increment_odometer(self, miles):
        self.odometer_reading += miles
        

class ElectricCar(Car):
    def __init__(self, make, model, year):
        Car.__init__(self, make, model, year)




my_tesla = ElectricCar(tesla, model s, 2016)
print(my_tesla.get_descriptive_name())

------------------line----------------------
2016 Tesla Model S

  这里Car就是ElectricCar的“父类” 或 “超类”, ElectricCar就是Car的“子类” 或 “派生类”。

  代码“Car.__init__(self, make, model, year)”,让Python通过调用Car类中的__init__(),让ElectricCar实例包含父类的所有属性。

  让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法,为电动汽车添加特有的属性(电瓶)。示例代码:

class Car(object):
    -- snip --

class ElectricCar(Car):
    def __init__(self, make, model, year):
        Car.__init__(self, make, model, year)
        self.battery_size = 70

    def describe_battery(self):
        print("This car has a " + str(self.battery_size) + "-kWH battery.")


my_tesla = ElectricCar(tesla, model s, 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

------------------line----------------------
2016 Tesla Model S This car has a 70-kWH battery.

  有的时候父类的一些方法可能不子类的一些特性,我们需要对父类的方法重新构造,我们可在子类中重新定义一个这样的方法,即与要重写的父类的方法同名。假如Car类中有fill_gas_tank()方法,我们在ElectricCar中重构。示例代码:

class ElectricCar(Car):
    -- snip --

    def fill_gas_tank(self):
        print("This car does‘t need a gas tank!")

  记住,先继承,再重构。

  

  Python支持多重继承,即一个派生类可以继承多个基类。

  多个类的继承可以形成层次关系,通过类的方法mro()或类的属性__mro__可以输出其继承的层次关系。例如:

class A: pass


class B(A): pass


class C(B): pass


class D(A): pass


class E(B, D): pass


print(D.mro())
print(E.__mro__)

------------------line----------------------

[<class ‘__main__.D‘>, <class ‘__main__.A‘>, <class ‘object‘>]
(<class ‘__main__.E‘>, <class ‘__main__.B‘>, <class ‘__main__.D‘>, <class ‘__main__.A‘>, <class ‘object‘>)

 

 

 


 

 

  附1,练习代码:

class SchoolMember(object):
    members = 0

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
        self.enroll()

    def enroll(self):
        print("just enrolled a school member [%s] ." % self.name)
        SchoolMember.members += 1

    def tell(self):
        print("------%s info------" % self.name)
        for k,v in self.__dict__.items():
            print("\t",k,v)



    def __del__(self):
        print("开除了[%s]..." % self.name)
        SchoolMember.members += 1


class Teacher(SchoolMember):
    def __init__(self, name, age, sex, salary, course):
        SchoolMember.__init__(self, name, age, sex)
        self.salary = salary
        self.course = course

    def teaching(self):
        print("Teacher [%s] is teaching [%s]." % (self.name, self.course))


class Student(SchoolMember):
    def __init__(self, name, age, sex, course, tuition):
        SchoolMember.__init__(self, name, age, sex)
        self.course = course
        self.tuition = tuition
        self.amount = 0

    def pay_tuition(self, amount):
        print("Student [%s] has just paied [%s]."  % (self.name, amount))
        self.amount += amount


t1 = Teacher("Alex", 33, "M", 2000, "Python")
s1 = Student("John", 20, "M", "Python", 30000)

 


 

  附2,关于新旧类的问题:

  写法1,又称经典类写法:

    基类名.__init__(self,基类中的属性) 

  写法2,又称新式类写法:

    Python 2.7中:

    super(子类名,self).__init__(基类中的属性)

    Python 3.x中:

    super().__init__(基类中的属性)

  注:在Python 2.7中使用继承时,务必在定义父类时在括号内指定object。

 

 

  

1.26 Python知识进阶 - 继承