一、类和对象
稍微有点编程的基础的人都知道面向对象编程,我们现在使用的大部分高级编程语言都支持面向对象编程。把一组数据和处理数据的方法组成对象,把行为相同的对象归纳为类,通过封装隐藏对象的内部细节,通过继承实现类的特化和泛化,通过多态实现基于对象类型的动态分派。
在面向对象编程中,类是一个抽象的概念,对象是一个具体的概念。我们把同一类对象的共同特征抽取出来就是一个类,比如我们经常说的人类,这是一个抽象概念,而我们每个人就是人类的这个抽象概念下的实实在在的存在,也就是一个对象。简而言之,类是对象的蓝图和模板,对象是类的实例,是可以接受消息的实体。
在面向对象编程的世界中,一切皆为对象,对象都有属性和行为,每个对象都是独一无二的,而且对象一定属于某个类。对象的属性是对象的静态特征,对象的行为是对象的动态特征。也就是说,如果我们把拥有共同特征的对象的属性和行为都抽取出来,就可以定义出一个类。
1、定义类
在Python中,可以使用class
关键字加上类名来定义类,写在类里面的函数我们通常称之为方法,方法就是对象的行为,方法的第一个参数通常都是self
,它代表了接收这个消息的对象本身。
class Car:
def start(self):
print('汽车启动了')
def car_brand(self,brand_name):
print(f'汽车品牌是{brand_name}')
对象名字首字母一般用大写表示
2、创建和使用对象
在我们定义好一个类之后,可以使用构造器语法来创建对象。
car1=Car()
car2=Car()
print(car1) #<__main__.Car object at 0x000002E14415C490>
上面我们创建了两个对象,分别为car1和car2,接下来,我们调用对象的方法,即创建类时定义的两个方法。两个方法的第一个参数self代表了接收消息的汽车对象,car_brand方法的第二个参数是汽车的品牌名称。
#调用start方法,有两种方式调用
#第一种是通过“对象.方法”调用方法,点前面的对象就是接收消息的对象
#第二种是通过“类.方法”调用方法,第一个参数是接收消息的对象
car1.start() #汽车启动了
Car.start(car1) #汽车启动了
car1.car_brand('比亚迪') #汽车品牌是比亚迪
Car.car_brand(car1,'比亚迪') #汽车品牌是比亚迪
我们一般比较常用的是第一种方法。第二种方法相对于第一种方法而言,第二种方法更容易理解一点。
3、__init__
方法
在我们上面创建的汽车对象只有行为没有属性,如果想对汽车对象定义属性,我们可以为类添加一个__init__
方法。在创建对象时,通过自动执行__init__
方法,完成对象对内存的初始化,也就是把对象数据放到内存空间中。所以我们可以添加__init__
方法为对象指定属性,同时完成对属性赋初始值的操作,因此,该方法也被称为初始化方法。
class Car:
def __init__(self, brand_name, color):
self.brand_name = brand_name
self.color = color
def start(self):
print('汽车启动了')
def car_brand(self):
print(f'那辆{self.color}汽车品牌是{self.brand_name}')
# 由于初始化方法除了self之外还有两个参数
# 所以调用Car类的构造器创建对象时要传入这两个参数
car1=Car('比亚迪','蓝色')
car1.start() #汽车启动了
car1.car_brand() #那辆蓝色汽车品牌是比亚迪
4、__repr__
方法
在python中,这种双下划线开头和结尾的方法都是有特殊用途的方法,我们一般称之为魔法方法。__repr__
也是其中一个,在上面定义对象时,我们用print将其打印出来了,但是打印出来的是对象的内存地址,如果我们想要打印自定义信息,就需要用到这个魔法方法。
class Car:
# 其他方法在这里就不写了,上面有
def __repr__(self):
return f'{self.brand_name},{self.color}'
print(car1) #比亚迪,蓝色
print(type(car1)) #<class '__main__.Car'>
print(car1.__repr__()) #比亚迪,蓝色
print(type(car1.__repr__())) #<class 'str'>
5、__new__
方法
__new__
方法是构建对象的方法,之前的__init__
方法是初始化构建出来的对象,不过一般我们都不需要重新定义__new__
方法。该方法至少要有一个参数cls,代表要实例化的类,且必须返回当前类的对象,不然没法执行init方法。
二、练习
题目:制作简单的游戏战斗
1、创建三个游戏人物,分别是:
- 小红,女,18,初始战斗力1000
- 小明,男,20,初始战斗力1800
- 小紫,女,19,初始战斗力2500
2、游戏场景,分别:
- 草丛战斗,消耗200战斗力
- 自我修炼,增长100战斗力
- 多人游戏,消耗500战斗力
class Game:
def __init__(self, name, gender, age, volume):
self.name = name
self.gender = gender
self.age = age
self.volume = volume
self.surplus_volume = volume
# 草丛战斗
def grass_battle(self):
self.surplus_volume -= 200
print(f'草丛战斗,消耗200战斗力,还剩下{self.surplus_volume}战斗力')
# 自我修炼
def practice(self):
self.surplus_volume += 100
print(f'自我修炼,增长100战斗力,还剩下{self.surplus_volume}战斗力')
# 多人游戏
def mary_battle(self):
self.surplus_volume -= 500
print(f'多人游戏,消耗500战斗力,还剩下{self.surplus_volume}战斗力')
def __repr__(self):
return f'{self.name},{self.gender},{self.age},初始战斗力{self.volume}'
g1 = Game('小红', '女', 18, 1000)
g2 = Game('小明', '男', 20, 1800)
g3 = Game('小紫', '女', 19, 2500)
'''
返回:
小红,女,18,初始战斗力1000
小明,男,20,初始战斗力1800
小紫,女,19,初始战斗力2500
'''
print(g1)
print(g2)
print(g3)
'''
返回:
草丛战斗,消耗200战斗力,还剩下800战斗力
自我修炼,增长100战斗力,还剩下1900战斗力
多人游戏,消耗500战斗力,还剩下2000战斗力
'''
g1.grass_battle()
g2.practice()
g3.mary_battle()