Python 第六章 类

6. 类

6.1 创建和使用类

    1、创建类

    面向对象编程是最有效的软件编写之一,在面向对象编程中,编写表示现实生活中的事情和情景的类,并基于这些类来创建对象。
    写类时,你定义一大类对象都有的通用行为;基于类创建对象时,每个对象都自动具备这种通用行为,然后可根据具体需要赋予每个对象独立的个性

class Dog():
    """模拟小狗动作"""
    
    def __init__(self, name, age):
        """初始化name和age"""
        """获取存储在形参name和age中的值,并将其存储到变量name和age中,
        然后该变量被关联到当前创建的实例
        """
        self.name = name
        self.age = age
        
    def sit(self):
        """模拟小狗蹲下"""
        print(self.name.title() + ' is now sitting.')
        
    def roll_over(self):
        """模拟小狗打滚"""
        print(self.name.title() + ' rolled over!')

    2、方法 __ init __()

    Python 中,首字母大写的名称指的是类,类中的函数称为方法__ init __() 是一个特殊方法,开头和末尾各有两个下划线,这是一种约定,旨在避免Python默认方法与普通方法发生名称冲突

    上述 __ init __() 方法中包含了三个形参:self、name和age,其中 self 是自动生成的,必不可少且必须在其他形参之前,因为Python 在调用 __ init __() 方法创建实例时,将自动传入实参 self,每个与类相关联的方法都自动传递实参 self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法

    3、根据类创建实例
    通常用小写名称表示根据类创建的实例。

class Dog():
    """模拟小狗动作"""

    def __init__(self, name, age):
        """初始化name和age"""
        self.name = name
        self.age = age

    def sit(self):
        """模拟小狗蹲下"""
        print(self.name.title() + ' is now sitting.')

    def roll_over(self):
        """模拟小狗打滚"""
        print(self.name.title() + ' rolled over!')


"""创建实例"""
my_dog = Dog('xiaohei', 6)
print("My dog's name is " + my_dog.name.title() + '.')
print('My dog is ' + str(my_dog.age) + ' years old.')
"""调用方法,使用句点表示法来调用"""
my_dog.sit()
my_dog.roll_over()

输出:

My dog's name is Xiaohei.
My dog is 6 years old.
Xiaohei is now sitting.
Xiaohei rolled over!

进程已结束,退出代码 0

6.2 使用类和实例

    1、使用类和实例

    下面来编写一个表示汽车的类,它存储了相关汽车的信息,还有一个汇总信息的方法。

class Car():
    """模拟汽车"""
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year

    def get_descriptive_name(self):
        """返回整洁的描述信息"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()


new_car = Car('audi', 'a4', 2016)
print(new_car.get_descriptive_name())

输出:

2016 Audi A4

进程已结束,退出代码 0

    2、给属性指定默认值

    类中每个属性都必须有初始值,哪怕是0或空字符串。如设置默认值时在方法 __ init __ () 内指定初始值,就无需包含为它提供初始值的形参

    下面添加一个名为 odomenter_reading ,其初始值为0,注意在输出时调用改参数必须将其数据类型给为 str,即使用 str(odomenter_reading) 将其改变为字符串

class Car():
    """模拟汽车"""
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odomenter_reading = 0  # 添加新属性

    def get_descriptive_name(self):
        """返回整洁的描述信息"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    def read_odomenter(self):
        """打印一条指出汽车历程的信息"""
        print('This car has ' + str(self.odomenter_reading) + ' miles on it.')


new_car = Car('audi', 'a4', 2016)
print(new_car.get_descriptive_name())
new_car.read_odomenter()

输出:

2016 Audi A4
This car has 0 miles on it.

进程已结束,退出代码 0

    3、修改属性的值

    – 直接修改属性值
    要修改属性值,最简单的方法是通过实例直接访问它。

class Car():
    """模拟汽车"""
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odomenter_reading = 0  # 添加新属性

    def get_descriptive_name(self):
        """返回整洁的描述信息"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    def read_odomenter(self):
        """打印一条指出汽车历程的信息"""
        print('This car has ' + str(self.odomenter_reading) + ' miles on it.')


new_car = Car('audi', 'a4', 2016)
print(new_car.get_descriptive_name())
new_car.odomenter_reading = 23  # 直接访问属性值并进行修改
new_car.read_odomenter()

输出:

2016 Audi A4
This car has 23 miles on it.

进程已结束,退出代码 0

    – 通过方法修改属性值
    如果有替你更新属性的方法,那你就无需直接访问属性,而是可将值传递给一个方法,让它在内部进行更新。

class Car():
    """模拟汽车"""
    def __init__(self, make, model, year):
        """初始化描述汽车的属性"""
        self.make = make
        self.model = model
        self.year = year
        self.odomenter_reading = 0  # 添加新属性

    def get_descriptive_name(self):
        """返回整洁的描述信息"""
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    def read_odomenter(self):
        """打印一条指出汽车历程的信息"""
        print('This car has ' + str(self.odomenter_reading) + ' miles on it.')

    def update_odomenter(self, mileage):
        """将里程表读数设置为指定值,在方法内部更新"""
        self.odomenter_reading = mileage


new_car = Car('audi', 'a4', 2016)
print(new_car.get_descriptive_name())
new_car.update_odomenter(24)  # 添加方法进行属性值修改
new_car.read_odomenter()

输出:

2016 Audi A4
This car has 24 miles on it.

进程已结束,退出代码 0

    – 通过方法对属性值进行递增
    有时需要将属性值递增特定量,而不是将其设置为全新值,添加一个方法来实现。

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


my_used_car = Car('subaru', 'outback', 2013)
print(my_used_car.get_descriptive_name())

my_used_car.update_odometer(2500)
my_used_car.read_odometer()

my_used_car.increment_odometer(100)
my_used_car.read_odometer()

输出:

2013 Subaru Outback
This car has 2500 miles on it.
This car has 2600 miles on it.

进程已结束,退出代码 0

6.3继承

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

    1、子类的方法 __ init __()

    创建子类实例时,Python 首先需要完成的任务是给父类所有属性赋值,此时子类的 __ init __() 方法需要施以援手

例:下面模拟一个电动汽车类,它是以前面的汽车类为父类创建。

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', 'model Y', 2021)
print(my_tesla.get_descriptive_name())

输出:

2021 Tesla Model Y

进程已结束,退出代码 0

    super() 是一个特殊函数,帮助 Python 将父类和子类关联起来super().init(make, model, year) 这句代码让 Python 调用父类 Car 的 __ init __()方法进行初始化,让 ElectricCar 实例包含父类的所有属性父类也称为(superclass),名称 super 因此而来

    2、给子类定义属性和方法

    一个子类继承一个类后,可添加区分子类和父类的所需的新属性和方法
例:下面添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法,我们将存储电瓶容量 battery_size,并编写一个打印点评描述的方法 describe_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 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 hattery.")


my_tesla = ElectricCar('tesla', 'model Y', 2021)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

输出:

2021 Tesla Model Y
This car has a 70-KWh hattery.

进程已结束,退出代码 0

    3、重写父类的方法

    对于父类的方法,只要它不符合子类模拟的实物行为,都可以对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名,这样 Python 将不会考虑这个父类方法,而只关注你在子类中定义的相应方法

例:假设 Car 类有一个名为 fill_gas_tank() 的方法,它对电动汽车来说毫无意义,因此对其进行重写。

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

    def fill_gas_tank(self):
        """描述汽车油箱"""
        print('This car has a gas tanks.')


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 hattery.")

    def fill_gas_tank(self):
        """电动汽车没有油箱"""
        print("This car doesn't need a gas tank.")


my_tesla = ElectricCar('tesla', 'model Y', 2021)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
my_tesla.fill_gas_tank()

输出:

2021 Tesla Model Y
This car has a 70-KWh hattery.
This car doesn't need a gas tank.

进程已结束,退出代码 0

    4、将实例用作属性

    使用代码模拟实物时,你会发现给类添加的细节越来越多:属性和方法清单以及文件都越来越长。这种情况可将类的一部分作为一个独立的类提取出来,将大型类拆分成多个协同工作的小类

例:不断给 ElectricCar 类添加细节,导致其中包含很多专门针对汽车电瓶的属性好方法,此时可将这些属性和方法提取出来,放到一个名为 Battery 的类中,并将 Battery 实例作为 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

    def fill_gas_tank(self):
        """描述汽车油箱"""
        print('This car has a gas tanks.')


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()  # 注意此处 Battery 后有括号

    def fill_gas_tank(self):
        """电动汽车没有油箱"""
        print("This car doesn't need a gas tank.")


my_tesla = ElectricCar('tesla', 'model Y', 2021)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

输出:

2021 Tesla Model Y
This car has a 70-KWh battery.

进程已结束,退出代码 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值