Python中文社区笨办法学Python

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

2020-07-25  本文已影响0人  pythonic生物人

本文介绍python面向“对象”编程。
首发于本人公众号:pythonic生物人

更好的阅读体验请戳:

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

目录

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


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


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


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

1、面向对象的基础概念

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

类的实例化或者对象

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

类的属性

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

类与类之间关系

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

image

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

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

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.

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

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

欢迎扫码关注公众号:pythonic生物人

干货,真香
上一篇下一篇

猜你喜欢

热点阅读