Python 继承

继承

  • 一个类继承另一个类时,它将自动获得另一个类的所有属性和方法,原有的类称为父类,而新类称为子类。
  • 子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

子类的方法 init()

  • 创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值,子类的方法需要__init__需要父类施以援手
  • 创建子类时,父类必须包含在当前文件中,且位于子类前面
  • 定义子类时,必须在括号内指定父类的名称
  • 方法__init__()接受创建Car实例所需的信息
  • super()是一个特殊函数,帮助Python将父类和子类关联起来,让Python调用父类的方法__init__(),让子类实例包含父类的所有属性,父类也称为超类(superclass),so-named:super
# 案例:创建一个简单的ElectricCar类版本,具备Car类的所有功能:
class Car():
    '''一次模拟汽车的简单尝试'''
    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):
        '''初始化父类的属性'''
        super().__init__(make,model,year)

my_tesla = ElectricCar('tesla','models',2016)
print(my_tesla.get_descriptive_name())
2016 Tesla Models

Python 2.7中的继承

  • 函数super()需要两个实参:子类名和对象self,为帮助Python将父类和子类关联起来。
  • 在使用继承时,务必在定义父类时在括号内指定object
class Car(object):
    def __init__(self, make, model, year):
        --snip--
class ElectricCar(Car):
    def __init__(self, make, model, year):
        super(ElectricCar, self).__init__(make, model, year)
            --snip--

给子类定义属性和方法

  • 让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。
# 案例:添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法,我们将存储电瓶容量,并编写一个打印电瓶描述的方法:
class Car():
    '''一次模拟汽车的简单尝试'''
    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):
        '''
        电动汽车的独特之处
        初始化父类的属性,再初始化电动汽车特有的属性
        '''
        super().__init__(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()
2016 Tesla Model S
This car has a 70-kwh battery.

重写父类的方法

  • 对于父类的方法,只要它不符合子类模拟的事务的行为,都可对其进行重写
  • 在子类中定义一个方法,即它与要重写的父类方法同名。so,Python将不会考虑这个父类的方法
# 案例:假设Car类有一个方法:fill_gas_tank()的方法,它对全东东骑车来书毫无意义,因此需要重写它
def ElectricCar(Car):
    --snip--
def fill_gas_tank():
    """ 电动汽车没有油箱 """
    print("This car doesn't need a gas tank!")

将实例用作属性

  • 子类中添加过多的属性时,可以针对该属性和方法,将这些属性和方法提取出来,放到另一个类中,并将新建的类实例用作该子类的属性
# 案例:不断给ElectricCar类添加细节,将这些细节提取出来,放到另一个类中,并将新建的类实例用作ElectricCar类的一个属性
class Car():
    '''一次模拟汽车的简单尝试'''
    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 Battery():
    '''一次模拟电动汽车电瓶的简单尝试'''
    def __init__(self,battery_size=70):
        '''
        初始化电瓶的属性
        '''
        self.battery_size = battery_size
    def describe_battery(self):
        '''打印一条描述电瓶容量的消息'''
        print("This car has a " + str(self.battery_size) + "-kwh battery.")

class ElectricCar(Car):
    '''电动汽车的独特之处'''
    def __init__(self,make,model,year):
        '''初始化父类的属性,再初始化电动汽车特有的属性'''
        super().__init__(make,model,year)
        self.battery = Battery()
        
my_tesla = ElectricCar('tesla','model s',2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
2016 Tesla Model S
This car has a 70-kwh battery.
# 给Battery类添加一个方法,根据电瓶容量报告汽车的续航里程:
class Car():
    '''一次模拟汽车的简单尝试'''
    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 Battery():
    '''一次模拟电动汽车电瓶的简单尝试'''
    def __init__(self,battery_size=70):
        '''
        初始化电瓶的属性
        '''
        self.battery_size = battery_size
    def describe_battery(self):
        '''打印一条描述电瓶容量的消息'''
        print("This car has a " + str(self.battery_size) + "-kwh battery.")
    def get_range(self):
        '''打印一条消息,指出电瓶车的续航里程'''
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:
            range = 270
        message = "This car can go approximately " + str(range)
        message += " milese on a full charge."
        print(message)
        
class ElectricCar(Car):
     def __init__(self,make,model,year):
        super().__init__(make,model,year)
        self.battery = Battery()

my_tesla = ElectricCar('tesla','model s',2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
my_tesla.battery.get_range()
2016 Tesla Model S
This car has a 70-kwh battery.
This car can go approximately 240 milese on a full charge.

练习

# 1.冰淇淋小店
# 冰淇淋小店是一种特殊的餐馆。编写一个名为 IceCreamStand 的类,让它继承你为完成练习 而编写的 Restaurant 类。
# Restaurant 类都可以.添加一个名为 flavors 的属性,用于存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋
# 的方法。创建一个 IceCreamStand 实例,并调用这个方法。
class Restaurant():
    def __init__(self,restaurant_name,cuisine_type):
        self.restaurant_name = restaurant_name.title()
        self.cuisine_type = cuisine_type
    def describe_restaurant(self):
        print(self.restaurant_name + "--值得拥有!" + self.cuisine_type + "--缓解压力!\n")
    def open_restaurant(self):
        print(self.restaurant_name + "店铺已开门,欢迎顾客前来畅饮!\n" )
class IceCreamStand(Restaurant):
    def __init__(self,restaurant_name,cuisine_type):
        super().__init__(restaurant_name,cuisine_type)
        self.flavors = []
       # self.flavors = ['玉米味','巧克力','红豆','珍珠奶茶']
    def display(self):
        print("本店今日打折口味有以下四种,请大家关注:\n")
        for flavor in self.flavors:
            print(flavor,end='\t')
gongcha = IceCreamStand('贡茶','冷饮')
gongcha.describe_restaurant()
gongcha.open_restaurant()
gongcha.flavors = ['玉米味','巧克力','红豆','珍珠奶茶']
gongcha.display()
贡茶--值得拥有!冷饮--缓解压力!

贡茶店铺已开门,欢迎顾客前来畅饮!

本店今日打折口味有以下四种,请大家关注:

玉米味	巧克力	红豆	珍珠奶茶	
# 2.管理员
# 管理员是一种特殊的用户。编写一个名为 Admin 的类,让它继承你为完成练习 9-3 或练习 9-5 而编写的 User 类。添加一个名为 privileges 的属性,用
# 于存储一个由字符串(如 "can add post" 、 "can delete post" 、 "can ban user" 等)组成的列表。编写一个名为 show_privileges() 的方法,它
# 显示管理员的权限。创建一个 Admin 实例,并调用这个方法。
class User():
    '''每个与类关联的方法调用都自动传递实参self,它是指向实例本身的引用,让实例能够访问类中的属性和方法'''
    def __init__(self,first_name,last_name,username,email,location):
        '''获取存储在形参中的值,并存储到变量中,然后该变量关联到当前创建的实例中'''
        '''以self为前缀的变量都可供类中的所有方法使用'''
        self.first_name = first_name
        self.last_name = last_name
        self.username = username.title()
        self.email = email
        self.location = location
    def describe_user(self):
        print("姓名:" +self.first_name + self.last_name)
        print("用户名:" + self.username)
        print("邮件:" + self.email)
        print("地址:" + self.location)
        print()
    def greet_user(self):
        print("欢迎尊敬的用户:" + self.username +"!" +"\n" )

class Admin(User):
    def __init__(self,first_name,last_name,username,email,location):
        super().__init__(first_name,last_name,username,email,location)
       # self.privileges = ["增加邮箱","删除邮箱","增加用户","删除用户","修改密码"]
        self.privileges =[]
    def show_privileges(self):
        print("管理员有以下权限:")
        for privilege in self.privileges:
            print("--"+ privilege)
user = Admin('张','三','zhang san','zhangsan@qq.com','北京')
user.privileges = ["增加邮箱","删除邮箱","增加用户","删除用户","修改密码"]
user.greet_user()
user.describe_user()
user.show_privileges()
欢迎尊敬的用户:Zhang San!

姓名:张三
用户名:Zhang San
邮件:zhangsan@qq.com
地址:北京

管理员有以下权限:
--增加邮箱
--删除邮箱
--增加用户
--删除用户
--修改密码
# 3.权限:
# 编写一个名为 Privileges 的类,它只有一个属性 —— privileges ,其中存储了练习2所说的字符串列表。将方法 show_privileges() 移到这
# 个类中。在 Admin 类中,将一个 Privileges 实例用作其属性。创建一个 Admin 实例,并使用方法 show_privileges() 来显示其权限。
class User():
    '''每个与类关联的方法调用都自动传递实参self,它是指向实例本身的引用,让实例能够访问类中的属性和方法'''
    def __init__(self,first_name,last_name,username,email,location):
        '''获取存储在形参中的值,并存储到变量中,然后该变量关联到当前创建的实例中'''
        '''以self为前缀的变量都可供类中的所有方法使用'''
        self.first_name = first_name
        self.last_name = last_name
        self.username = username.title()
        self.email = email
        self.location = location
    def describe_user(self):
        print("姓名:" +self.first_name + self.last_name)
        print("用户名:" + self.username)
        print("邮件:" + self.email)
        print("地址:" + self.location)
        print()
    def greet_user(self):
        print("欢迎尊敬的用户:" + self.username +"!" +"\n" )


            
class Admin(User):
    def __init__(self,first_name,last_name,username,email,location):
        super().__init__(first_name,last_name,username,email,location)
        self.privileges = Privileges()

class Privileges():
    def __init__(self,privileges=[]):
        self.privileges = privileges
    def show_privileges(self):
        print("管理员有以下权限:")
        if self.privileges:
            for privilege in self.privileges:
                print("--"+ privilege)
            
user = Admin('张','三','zhang san','zhangsan@qq.com','北京')
user.greet_user()
user.describe_user()
user.privileges.privileges = ["增加邮箱","删除邮箱","增加用户","删除用户","修改密码"]
user.privileges.show_privileges()

欢迎尊敬的用户:Zhang San!

姓名:张三
用户名:Zhang San
邮件:zhangsan@qq.com
地址:北京

管理员有以下权限:
--增加邮箱
--删除邮箱
--增加用户
--删除用户
--修改密码
# 4.电瓶升级
# 给 Battery 类添加一个名为 upgrade_battery() 的方法。这个方法检查电瓶容量,如果它不是 85 ,就将它
# 设置为 85 。创建一辆电瓶容量为默认值的电动汽车,调用方法 get_range() ,然后对电瓶进行升级,并再次调用 get_range() 。你会看到这辆汽车的续航里程增
# 加了。
class Car():
    """A simple attempt to represent a car."""

    def __init__(self, manufacturer, model, year):
        """Initialize attributes to describe a car."""
        self.manufacturer = manufacturer
        self.model = model
        self.year = year
        self.odometer_reading = 0
        
    def get_descriptive_name(self):
        """Return a neatly formatted descriptive name."""
        long_name = str(self.year) + ' ' + self.manufacturer + ' ' + self.model
        return long_name.title()
    
    def read_odometer(self):
        """Print a statement showing the car's mileage."""
        print("This car has " + str(self.odometer_reading) + " miles on it.")
        
    def update_odometer(self, mileage):
        """
        Set the odometer reading to the given value.
        Reject the change if it attempts to roll the odometer back.
        """
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    
    def increment_odometer(self, miles):
        """Add the given amount to the odometer reading."""
        self.odometer_reading += miles

class Battery():
    """A simple attempt to model a battery for an electric car."""

    def __init__(self, battery_size=60):
        """Initialize the batteery's attributes."""
        self.battery_size = battery_size

    def describe_battery(self):
        """Print a statement describing the battery size."""
        print("This car has a " + str(self.battery_size) + "-kWh battery.")

        
    def get_range(self):
        """Print a statement about the range this battery provides."""
        if self.battery_size == 60:
            range = 140
        elif self.battery_size == 85:
            range = 185
            
        message = "This car can go approximately " + str(range)
        message += " miles on a full charge."
        print(message)

    def upgrade_battery(self):
        """Upgrade the battery if possible."""
        if self.battery_size == 60:
            self.battery_size = 85
            print("Upgraded the battery to 85 kWh.")
        else:
            print("The battery is already upgraded.")
    
        
class ElectricCar(Car):
    """Models aspects of a car, specific to electric vehicles."""

    def __init__(self, manufacturer, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(manufacturer, model, year)
        self.battery = Battery()


print("Make an electric car, and check the battery:")
my_tesla = ElectricCar('tesla', 'model s', 2016)
my_tesla.battery.describe_battery()
 
print("\nUpgrade the battery, and check it again:")
my_tesla.battery.upgrade_battery()
my_tesla.battery.describe_battery()

print("\nTry upgrading the battery a second time.")
my_tesla.battery.upgrade_battery()
my_tesla.battery.describe_battery()

Make an electric car, and check the battery:
This car has a 60-kWh battery.

Upgrade the battery, and check it again:
Upgraded the battery to 85 kWh.
This car has a 85-kWh battery.

Try upgrading the battery a second time.
The battery is already upgraded.
This car has a 85-kWh battery.
posted @ 2020-11-25 15:30  野哥李  阅读(5)  评论(0编辑  收藏  举报  来源