python3基础10面向“对象”编程
本文介绍python面向“对象”编程。
首发于本人公众号:pythonic生物人
更好的阅读体验请戳:
目录
1、面向对象的基础概念
类
类的实例化或者对象
类的属性
类与类之间关系
2、自定义类
创建自定义类
创建类实例
调用类变量属性
调用类方法属性
类的查看操作
使用类和实例
给属性指定默认值
修改属性值
3、面向对象三大共性
继承
创建子类
给子类定义新的属性和方法(extend即派生)
在子类中重写父类的方法(override)
将实例作为变量属性
多态和封装
4、导入类
导入单个类
从一个模块中导入多个类
导入整个模块
导入模块中的所有类
1、面向对象的基础概念
类
具有很多共同特性的事物,可以理解为一个模板。例如下图王者某耀中定位的坦克类;车类;狗类。 image image image类的实例化或者对象
具体的某个事物,具有自己的特性。例如,上图中定位为坦克类英雄中的猪八戒、嫦娥、孙策等;车类中的宝马、奥迪、法拉利等;狗类中的101斑点狗、旺财、来福等。
类的属性
分为变量属性(一般为名词,如下图DOG类中 Breed、Size、Age、Color)和方法属性(即子函数,一般为动词,如下如中狗可以Eat、Sleep、Sit、Run)。 image类与类之间关系
子类直接拥有父类的属性和方法称为继承(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
欢迎扫码关注公众号:pythonic生物人