面向对象
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。
面向对象技术简介
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
创建类
使用 class 语句来创建一个新类,class 之后为类的名称并以冒号结尾:
class ClassName:
'类的帮助信息' #类文档字符串
class_suite #类体
或者理解:
class 类名:
属性 #类文档字符串
方法 #类体
举个例子:
# 创建一个类
class Cat:
#__代表告诉系统仅在初始化期间使用,和C语言意义一致。在此处__init__在创建对象的时候调用
def __init__(self,name,age):
self.name = name
self.age = age
self.clr = 0
def Color(self,color): #self 代表是对象,哪个对象调用该类中的方法,self就代表该对象
self.clr = color
print("The cat is %s" %(self.clr))
def introduce(self):
#print("name:%s age:%s" %(Tom.name,Tom.age)) # 如果JFM对象调用改方法,打印的还是Tom的信息,不是我们想要的结果
print("name:%s age:%s" %(self.name,self.age)) # 使用self,来打印不同对象中的信息
'''
# 方法一:创建对象,并初始化类中的属性
# 创建一个对象
Tom = Cat()
# 初始化类中的属性
Tom.name = "Tom"
Tom.age = 18
'''
# 方法二:在创建对象的同时采用__init__初始化类中的属性
Tom = Cat("Tom",18)
# 调用方法
Tom.Color("White")
Tom.introduce()
'''
Jfm = Cat()
Jfm.name = "JiaFeiMao"
Jfm.age = 20
'''
Jfm = Cat("JiaFeiMao",20)
Jfm.Color("Black")
Jfm.introduce()
#运行结果:
ubuntu@ubuntu16:/work/python/7-day$ python3 1-类.py
The cat is White
name:Tom age:18
The cat is Black
name:JiaFeiMao age:20
__init__方法
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。以学生类为例,通过定义一个特殊的__init__方法,在创建实例的时候,就把name,age等属性绑上去:
def __init__(self,name,age):
self.name = name
self.age = age
注意:特殊方法“init”前后分别有两个下划线!!!
注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去:
Tom = Cat("Tom",18)
__str__方法
class Cat:
"""定义一个猫类"""
def __init__(self, new_name, new_age):
"""在创建完对象之后 会自动调用, 它完成对象的初始化的功能"""
# self.name = "汤姆"
# self.age = 20
self.name = new_name
self.age = new_age # 它是一个对象中的属性,在对象中存储,即只要这个对象还存在,那么这个变量就可以使用
# num = 100 # 它是一个局部变量,当这个函数执行完之后,这个变量的空间就没有了,因此其他方法不能使用这个变量
def __str__(self):
"""返回一个对象的描述信息"""
# print(num)
return "名字是:%s , 年龄是:%d" % (self.name, self.age)
def eat(self):
print("%s在吃鱼...." % self.name)
def drink(self):
print("%s在喝可乐..." % self.name)
def introduce(self):
# print("名字是:%s, 年龄是:%d" % (汤姆的名字, 汤姆的年龄))
# print("名字是:%s, 年龄是:%d" % (tom.name, tom.age))
print("名字是:%s, 年龄是:%d" % (self.name, self.age))
# 创建了一个对象
tom = Cat("汤姆", 30)
print(tom)
ubuntu@ubuntu16:/work/python/7-day$ python3 3.py
名字是:汤姆 , 年龄是:30
1.在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法
2.当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
3.__str__方法需要返回一个字符串,当做这个对象的描写
应用1-烤地瓜例子
class sweet_potato:
def __init__(self):
self.cook_status = "生的"
self.cook_total_time = 0
self.cook_items = []
def __str__(self):
return "地瓜熟了没:%s(%d),加的佐料有:%s" %(self.cook_status,self.cook_total_time,str(self.cook_items))
def cook(self,cook_time):
self.cook_total_time += cook_time
if self.cook_total_time >= 0 and self.cook_total_time < 3:
self.cook_status = "生的"
elif self.cook_total_time >= 3 and self.cook_total_time < 6:
self.cook_status = "半生不熟"
elif self.cook_total_time >= 6 and self.cook_total_time < 9:
self.cook_status = "熟了"
elif self.cook_total_time >= 9:
self.cook_status = "烤糊了"
def add_cook_items(self,item):
self.cook_items.append(item)
digua = sweet_potato()
digua.cook(1)
digua.cook(1)
digua.add_cook_items("烧烤酱")
print(digua)
digua.cook(1)
digua.add_cook_items("番茄酱")
digua.cook(1)
digua.cook(1)
print(digua)
digua.cook(1)
digua.add_cook_items("孜然粉")
digua.cook(1)
digua.cook(1)
print(digua)
digua.cook(1)
digua.add_cook_items("盐")
digua.cook(1)
print(digua)
digua.cook(1)
print(digua)
#结果:
ubuntu@ubuntu16:/work/python/7-day$ python3 4-烤地瓜.py
地瓜熟了没:生的(2),加的佐料有:['烧烤酱']
地瓜熟了没:半生不熟(5),加的佐料有:['烧烤酱', '番茄酱']
地瓜熟了没:熟了(8),加的佐料有:['烧烤酱', '番茄酱', '孜然粉']
地瓜熟了没:烤糊了(10),加的佐料有:['烧烤酱', '番茄酱', '孜然粉', '盐']
地瓜熟了没:烤糊了(11),加的佐料有:['烧烤酱', '番茄酱', '孜然粉', '盐']
应用2-存放家具
#创建一个Home类
class Home:
def __init__(self,new_area,new_info,new_addr):
self.area = new_area
self.info = new_info
self.addr = new_addr
self.free_space = new_area
self.contain_items = []
def __str__(self):
msg = "房子的面积:%d,房子的户型:%s,房子的地址:%s," %(self.area,self.info,self.addr)
msg += "房子中有什么东西:%s,房子剩余空间大小:%d" %(str(self.contain_items),self.free_space)
return msg
def add_items(self,item):
self.free_space -= item.get_area()
self.contain_items.append(item.get_name())
#创建一个Bed类
class Bed:
def __init__(self,new_name,new_area):
self.area = new_area
self.name = new_name
def __str__(self):
return "这个床是什么牌子的:%s,占用多大面积:%s" %(self.name,self.area)
def get_area(self):
return self.area
def get_name(self):
return self.name
house = Home(129,"三室一厅","上海徐家汇")
print(house)
bed = Bed("席梦思",4)
print(bed)
house.add_items(bed)#参数是可以传对象的
print(house)
#结果:
ubuntu@ubuntu16:/work/python/7-day$ python3 5-存放家具.py
房子的面积:129,房子的户型:三室一厅,房子的地址:上海徐家汇,房子中有什么东西:[],房子剩余空间大小:129
这个床是什么牌子的:席梦思,占用多大面积:4
房子的面积:129,房子的户型:三室一厅,房子的地址:上海徐家汇,房子中有什么东西:['席梦思'],房子剩余空间大小:125