【Python基础知识】(八)类和继承

类的基本概念

  Python是一门面向对象的编程语言,在程序设计中,可通过编写来模拟现实世界中的事物和情景,并基于这些类来创建对象。基于类创建对象时,每个对象都自动具备类中定义的行为,这个过程被称为实例化

类的创建和使用

1、创建类

class Dog():
    '''创建Dog类'''
    
    def __init__(self, name, age):  #self是指向实例的__init__函数的特殊参量
        '''初始化属性name和age'''
        self.name = name
        self.age = age
        
    def sit(self):  #函数中包含__init__函数中的self.name,故需要指向实例的__init__函数的形参self作为这个sit函数的参量,下面的roll_over函数同
        '''模拟小狗被命令时蹲下'''
        print(self.name.title() + " is now sitting.")
        
    def roll_over(self):
        '''模拟小狗被命令时打滚'''
        print(self.name.title() + " rolled over!")

  按照约定,在Python中首字母大写的名称指的是类。

  类中的函数被称为方法(故引用时使用点号连接)。__init__()是一个Python中的默认方法,每当你根据Dog类创建新实例时,Python都会自动运行它。__init__()开头和末尾各有两个下划线,用于与普通的方法区分。

  __init__()包含3个形参:self、name和age。其中self必不可少且需位于其他形参之前,它是一个指向实例本身的引用(类似于指针),让实例能够作为类中函数的参数访问类中的属性与方法。当调用__init__()方法创建实例时,Python将自动传入实参self,也就是说我们在创建实例时不需要给self这个形参赋值,而只需给后面的其他形参赋值即可。

  在Dog类定义的另外两个方法中,由于这些方法不需要额外的信息,如名字或年龄,因此它们只有一个必带的形参self。在未来的开发中,可以扩展这些方法以模拟实际情况,如插入小狗蹲下和打滚动画的代码。

2、根据类创建实例

  类可以视为有关如何创建实例的说明。Dog类是一系列说明,让Python知道如何创建表示特定小狗的实例。

class Dog():
    --snip--
                                
my_dog = Dog('willie', 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 Willie.
My dog is 6 years old.
Willie is now sitting.
Willie rolled over!

3、给属性指定默认值

  类中的每个属性都必须有初始值。当给某个属性指定默认值后,就无需包含为它提供初始值的形参。

class Car():
    '''创建Car类'''
    
    def __init__(self, make, model, year):
        '''初始化描述汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
        #添加名为odometer_reading的属性,将初始值设置为0
        self.odometer_reading = 0    
        
    def get_descriptive_name(self):
        '''返回描述性信息'''
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    
    #添加名为read_odometer的调用odometer_reading的函数
    def read_odometer(self):
        '''打印一条指出汽车里程的消息'''
        print("This car has " + str(self.odometer_reading) + 
              " miles on it.")
        
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
#调用read_odometer函数,打印汽车行驶里程
my_new_car.read_odometer()

输出为:

2016 Audi A4
This car has 0 miles on it.

以下写法与上述代码等价

class Car():
    '''创建Car类'''
    
    def __init__(self, make, model, year, odometer_reading = 0):  #将带默认值的参量写入括号
        '''初始化描述汽车的属性'''
        self.make = make
        self.model = model
        self.year = year
        #添加名为odometer_reading的属性,将初始值设置为0
        self.odometer_reading = odometer_reading  #带默认值变量的赋值
        '''或写成:self.odometer_reading = 0'''
def get_descriptive_name(self): '''返回描述性信息''' long_name = str(self.year) + ' ' + self.make + ' ' + self.model return long_name.title() #添加名为read_odometer的调用odometer_reading的函数 def read_odometer(self): '''打印一条指出汽车里程的消息''' print("This car has " + str(self.odometer_reading) + " miles on it.") my_new_car = Car('audi', 'a4', 2016, 0) print(my_new_car.get_descriptive_name()) #调用read_odometer函数,打印汽车行驶里程 my_new_car.read_odometer()

4、修改属性的值

(1)直接修改

my_new_car.odometer_reading = 23

(2)在类中定义可以修改属性的值的方法

class Car():
    --snip--

    def update_odometer(self, mileage):
        '''将里程数设置为指定的值'''
        self.odometer_reading = mileage

my_new_car.update_odometer(23)

(3)在类中定义可以使属性的值递增/递减变化的方法

class Car():
    --snip--

    def update_odometer(self, mileage):
        '''将里程数设置为指定的值'''
        self.odometer_reading = mileage

    def increment_odometer(self, miles):
        '''使读数递增指定的值'''
        self.odometer_reading += miles 

my_old_car.update_odometer(23)
my_old_car.increment_odometer(100)

类的继承

  编写类时,并非总要从空白开始。如果你想要在一个已有的类的基础上编写新的类,则可以使用继承。当一个类继承另一个类时,它将自动获得另一个类的所有属性和方法;原有的类称为父类,新类称为子类。子类继承了其父类所有属性和方法,同时还可以定义自己的属性和方法。

1、创建子类

class Car():
    --snip--

class ElectricCar(Car):
    '''由父类Car创建子类ElectricCar'''

    def __init__(self, make, model, year):
        '''初始化父类的属性,从而得到子类对应属性'''
        super().__init__(make, model, year)

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

  创建子类时,父类必须包含在当前文件中,且位于子类前面

  定义子类时,必须在括号内指明父类的名称。方法__init__()接收创建Car实例所需的信息。

  注意不同结构的命名方式:类的每个单词的首字母大写,不用下划线连接;而方法的单词全部小写,并用下划线连接

  super()是一个特殊函数,帮助Python将父类和子类关联起来,这行代码让Python调用父类的__init__()方法,从而让ElectricCar下的实例包含父类的所有属性。父类也被称为超类(superclass),super就得名于此。

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

  让一个类继承另一个类后,可在新类中添加独属于它新属性新方法

class Car():
    --snip--

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.describe_battery()

  本例在Car类的基础上创建了ElectricCar类,ElectricCar类继承了Car类的属性和方法,同时也根据自己的特点添加了特有的新的属性和方法。

  如果一个属性或方法是任何汽车都有的,而不是电动汽车所特有的,就应该将其加入Car类而不是ElectricCar类。

3、在子类中重写父类

  通过在子类中定义一个与要重写的父类方法同名的方法的方式,可将原父类中的方法“覆盖”掉,Python只会关注这个新的方法,而会忽略原来的方法。

class ElectricCar(Car):
    --snip--

    def fill_gas_tank(self):
        '''重写父类中包含的同名方法'''
        print("This car doesn't need a gas tank!")

4、创建多个类

  当类的属性和方法数量逐渐增多、变得越来越复杂时,可将大类的一个部分作为一个独立的类提取出来,也就是把一个大类拆分成若干个小类。

class Car():
    --snip--

class Battery():
    '''拆分出新的类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):
    '''被拆分后的大类'''
    super().__init__(make, model, year)
    '''指向新类的属性定义'''
    self.battery = Battery()

'''实例.属性->新类Battery,新类.方法->调用相关函数'''
my_tesla.battery.describe_battery()

类的导入

  假设我们已经编写了一个包含类的文件,文件名为car.py,在这个类中我们定义了CarElectricCar两个类(在同一个文件中存储的类最好具有一定的相关性),则有以下几种不同的导入方式。

从一个文件导入单个类:
from car import Car

从一个文件导入多个类:
from car import Car, ElectricCar

假设还有另一个模块,从不同模块中导入多个类:
from electric_car import Battery
from car import Car, ElectricCar

导入整个模块:
import  car

导入模块中所有类:
from car import *

  Python自带了Python标准库,里面有很多已经编写好的函数和类。通过函数和类的导入,你可以在你的程序中使用这些函数和类。

参考书籍:《Python编程:从入门到实践》

2020-07-22

原文地址:https://www.cnblogs.com/carl39/p/13353080.html