查看原文
其他

python3基础10面向“对象”编程

pythonic生物人 pythonic生物人 2022-09-11

"pythonic生物人"的第47篇分享


用python面向“对象”编程吧。

目录


1、面向对象的基础概念类的实例化或者对象类的属性类与类之间关系

2、自定义类创建自定义类创建类实例调用类变量属性调用类方法属性类的查看操作使用类和实例给属性指定默认值修改属性值

3、面向对象三大共性继承创建子类给子类定义新的属性和方法(extend即派生)在子类中重写父类的方法(override)将实例作为变量属性多态和封装

4、导入类导入单个类从一个模块中导入多个类导入整个模块导入模块中的所有类




正文开始啦

1、面向对象的基础概念

具有很多共同特性的事物,可以理解为一个模板。例如下图王者某耀中定位的坦克类;车类;狗类。

类的实例化或者对象

具体的某个事物,具有自己的特性。例如,上图中定位为坦克类英雄中的猪八戒、嫦娥、孙策等;车类中的宝马、奥迪、法拉利等;狗类中的101斑点狗、旺财、来福等。

类的属性

分为变量属性(一般为名词,如下图DOG类中 Breed、Size、Age、Color)和方法属性(即子函数,一般为动词,如下如中狗可以Eat、Sleep、Sit、Run)。

类与类之间关系

子类直接拥有父类的属性和方法称为继承(inheritance),例如英雄父类具有伤害、移动、控制等属性,坦克类、战士等子类直接继承;
子类可以自定义父类的属性,称为延伸(extend),例如坦克子类定义了从天而降的控制、射手定义了千里狙击的射法等;
子类可以覆盖父类的属性,称为重写(override),例如坦克重点加强控制、射手重点加强伤害等。


2、自定义类

创建自定义类

语法

class 类名():
"""类说明文档"""
类body

创建一个Dog类

class Dog():#python中,首字母大写的名称指的是类;定义一个Dog类;
    """模拟小狗"""#Dog类说明文档,描述Dog类的功能。
    
    """定义类构造方法"""
    def __init__(self,name,age):
        ##__init__
        #此处是init,而不是int;init前后分别有两个下划线;
        #定义“每个实例自己的特征”;
        #类中的函数称为方法,__init__是一个特殊方法,每当创建Dog类的实例时,python都会自动执行Dog.__init__();
        
        ##self
        #形参self必不可少,且必须位于其他形参的前面;
      #在实例化时自动将实例本身传给__init__的第一个参数self;
        #python调用__init__()方法创建Dog类实例时,self即为该实例;
        #每个与类相关联的方法调用都自动传递实参self ,它是一个“指向实例本身”的引用,让实例能够访问“类中的属性和方法”。 
        
        """定义Dog类的变量属性name, age"""
        #以self为前缀的变量称为Dog类的变量属性(名词),可供Dog类中的所有方法及任何实例访问这些变量。
        self.name = name        
        self.age = age
    
    """定义Dog类的方法属性,即子函数"""
    def sit(self):
        """模拟小狗坐下的sit方法"""
        print(self.name.title() + " is now sitting.")#sit方法中访问Dog类的name变量属性
    def roll_over(self):
        """模拟小狗打滚的roll_over方法"""
        print(self.name.title()+" rowlled over!")#roll_over方法中访问Dog类的name变量属性

创建类实例

语法: 类名(参数);
创建Dog类的my_dog实例。

my_dog = Dog("cai wang",6)
#相当于执行Dog.__init__("cai wang",6)
#创建一条名字为'cai wang' 、年龄为6岁的my_dog实例小狗;
#方法__init__() 创建一条name为'cai wang' 、age为6岁的my_dog实例小狗;

#执行完__init__()返回(方法__init__() 并未显式地包含return 语句)一个类似字典的对象,存储属于my_dog的属性和方法。
my_dog.__dict__

{'name': 'cai wang', 'age': 6}

调用类变量属性

语法:实例对象名.变量属性名

print("My dog's name is " + my_dog.name.title() + ".")#my_dog.name
print("My dog is " + str(my_dog.age) + " years old.") 

My dog's name is Cai Wang.
My dog is 6 years old.

调用类方法属性

语法:实例对象名.方法名()
#要调用方法, 可指定实例的名称(这里是my_dog ) 和要调用的方法, 并用句点分隔它们。

my_dog.sit()#调用sit方法
my_dog.roll_over()#调用roll_over方法

Cai Wang is now sitting.
Cai Wang rowlled over!

类的查看操作

dir(类名)#返回类属性和方法列表
类名.dict#存储类变量属性的字典,key为属性名,value为属性值
类名.name# 类的名字(字符串)
类名.doc# 类的说明文档
类名.base# 类的第一个父类
类名.bases# 类所有父类构成的元组
类名.module# 类定义所在的模块
类名.class# 实例对应的类(仅新式类中)

使用类和实例

类编写好后, 之后的工作都是在创建类的实例上。修改实例的属性(直接修改实例的属性或者编写方法修改属性)。

class Car():
    """模拟汽车"""
    def __init__(self, make, model, year):
        """初始化汽车属性"""
        self.make = make
        self.model = model
        self.year = year
    def get_descriptive_name(self):
        """返回完整的描述信息"""        
        long_name = " ".join((str(self.year),self.make,self.model))#在方法属性中访问变量属性的值self.make等。
        return long_name.title()
my_car = Car("audi","a4","2020")##创建Car类的一个实例
print(my_car.get_descriptive_name())#调用方法get_descriptive_name() 
  • 给属性指定默认值

类中的每个属性都必须有初始值,如果在方法__init__() 内设定了某个属性初始值,则不必在在__init__()的括号内指定该属性的形参。

class Car():
    """模拟汽车"""
    def __init__(self, make, model, year):#括号中不必设置默认值odometer_reading的形参。    
        """初始化汽车属性"""
        self.make = make
        self.model = model
        self.year = year        
        self.odometer_reading = 0#创建默认属性odometer_reading,设置默认值为0。
    def get_descriptive_name(self):
        """返回完整的描述信息"""
        #为在这个方法中访问属性的值,我们使用了self.make 、self.model 和self.year 。
        long_name = " ".join((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.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer() 

2016 Audi A4
This car has 0 miles on it.

  • 修改属性值

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

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 = " ".join((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.")

my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23#在实例my_new_car中修改属性odometer_reading的值为23
my_new_car.read_odometer()

2016 Audi A4
This car has 23 miles on it.

通过方法进行设置

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 = " ".join((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):#定义update_odometer方法修改属性的默认值
        """将里程表读数设置为指定的值"""
        self.odometer_reading = mileage      
        
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())

my_new_car.update_odometer(23)#调用了update_odometer()方法,并向它提供了实参23。
my_new_car.read_odometer()

2016 Audi A4
This car has 23 miles on it.

通过方法进行递增(增加特定的值)

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 = " ".join((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):
        """将里程表读数设置为指定的值"""
        self.odometer_reading = mileage
        
    def increment_odometer(self, miles):
        """将里程表读数增加指定的量"""
        self.odometer_reading += miles
my_used_car = Car('subaru', 'outback', 2020)
print(my_used_car.get_descriptive_name())

my_used_car.update_odometer(23500)
my_used_car.read_odometer()

my_used_car.increment_odometer(100)#increment_odometer方法使里程属性累加。
my_used_car.read_odometer()

2020 Subaru Outback
This car has 23500 miles on it.
This car has 23600 miles on it.


3、面向对象三大共性

多态、继承、封装

继承

继承主要是为了避免代码重复写,子类能从父类那拿来属性全部拿来,子类不需要从头开始;
一个类(子类或者派生类)继承另一个类或者多个类(superclass,基类、父类或者超类)时, 子类获得父类所有的属性和方法, 同时还可以定义自己的属性和方法;

  • 创建子类

在前面创建的父类Car的基础上创建子类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 += mile
        
        
##创建子类ElectricCar
class ElectricCar(Car):#定义子类时,必须在括号内指定父类的名称,继承多个父类时,多个父类之间逗号分割。
    """子类ElectricCar继承父类Car"""
    def __init__(self, make, model, year):
        """初始化父类的属性"""
        super().__init__(make, model, year)
        #super(源自superclass)方法让子类继承父类的方法。
        #super()帮助将父类和子类关联起来,即ElectricCar子类的调用父类Car的方法__init__()。

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

2016 Tesla Model S

  • 给子类定义新的属性和方法(extend即派生)

给电动汽车添加电瓶这个特有的变量属性, 及描述该属性的方法。我们将存储电瓶容量, 并编写一个打印电瓶描述的方法:

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 += mile
        
class ElectricCar(Car):
    """模拟电动车"""
    def __init__(self, make, model, year):
        """
        电动汽车的独特之处
        继承父类的属性, 定义电动车特有的属性
        """
        super().__init__(make, model, year)#继承父类属性
        self.battery_size = 70 #子类定义battery_size新属性,赋值70;        
    def describe_battery(self):#子类定义describe_battery新方法。
        """打印一条描述电瓶容量的消息"""
        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.

  • 在子类中重写父类的方法(override)

对于父类的方法, 都可对其进行重写以使其符合子类,子类和父类中被重写的方法名称相同,但是,子类中只会使用被重写后的方法。

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 += mile
    def fill_gas_tank(self):#子类中重写该方法
        """汽车有油箱"""
        print("This car  needs a gas tank!")   

class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    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.")
        
    def fill_gas_tank(self):
        #虽然与父类方法同名,但是子类中只会使用该重写后的方法。
        """电动汽车没有油箱"""
        print("This car doesn't need a gas tank!")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
my_tesla.fill_gas_tank()#此处调用ElectricCar中的方法fill_gas_tank,而不是Car中的方法fill_gas_tank。

2016 Tesla Model S
This car has a 70-kWh battery.
This car needs a 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 += mile
    def fill_gas_tank(self):
        """汽车有油箱"""
        print("This car  needs a gas tank!")  

#定义了一个名为Battery 的新类
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 += " miles on a full charge."
        print(message)

class ElectricCar(Car):
    """电动汽车的独特之处"""
    def __init__(self, make, model, year):
        """
        初始化父类的属性, 再初始化电动汽车特有的属性
        """
        super().__init__(make, model, year)
        self.battery = Battery()#每个ElectricCar实例都包含一个自动创建的Battery实例
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()#通过汽车的属性battery来调用describe_battery方法
my_tesla.battery.get_range()#通过汽车的属性battery来调用get_rang方法

2016 Tesla Model S
This car has a 70-kWh battery.
This car can go approximately 240 miles on a full charge.

多态和封装

略(先占坑)


4、导入类

将类存储在模块(.py结束的文件)中, 然后在主程序中导入所需的模块。

导入单个类

构建car.py模块:创建一个文件car.py,输入如下Car 类的代码。

 ##car.py
"""一个可用于表示汽车的类"""
#模块说明文档
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

构建主程序,在主程序中导入Car类,该方法可以使得主程序变得整洁。

from car import Car#打开模块car ,并导入其中的Car类。
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()

2016 Audi A4
This car has 23 miles on it.

从一个模块中导入多个类

from car import Car, ElectricCar

导入整个模块

import car

导入模块中的所有类

from 模块名 import *

参考资料

Python编程:从入门到实践
https://www.cnblogs.com/Eva-J/articles/7293890.html



参考资料

当前字母 :p
当前字母 :y
当前字母 :t
这是 pass 块
当前字母 :h
当前字母 :o
当前字母 :n


同系列文章

python3基础07函数(自定义)
python3基础08函数(python内置)
python3基础09列表推导式|迭代器|生成器|匿名函数


原创不易"点赞"、"在看"鼓励下呗



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存