• 1.26 Python知识进阶


    继承

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

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

      声明格式:

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

          类体

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

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

    class A(object): 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(object): 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("	",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。

      

  • 相关阅读:
    HDU 1429
    HDU 1622
    HDU 3335
    HDU 4160
    HDU 1350
    HDU 5086
    HDU 1300
    HDU 3047
    HDU 3038
    HDU 5100
  • 原文地址:https://www.cnblogs.com/topspeedking/p/6915915.html
Copyright © 2020-2023  润新知