面向对象编程
指的是一种编程思想
1.面向过程编程
核心是'过程'两字,基于流程编写程序
优点: 逻辑清晰,使复杂问题简单化
缺点: 可扩展性差
2.面向对象编程
核心是"对象"两个字,对象指的是特征与技能的结合体
基于该编程思想编写程序,类似于上帝造人,为每个类定义.
优点: 可扩展性高
缺点: 编写程序的复杂程度远高于面向过程思想
类
理解为一个模板,通过他创建出无数个具体实例.
对象
类本身不能直接使用,通过类创建出的实例--对象.才能使用.
类似于图纸与产品的关系,图纸(类)不能直接使用,通过图纸创造产品(对象)才能使用
属性
类中的所有变量称为属性.(变量名)
方法
类中的所有函数称之为方法,和函数不同是,类方法至少要包含一个self参数.类方法无法单独使用,只能个类的对象一起使用.
类
先定义类,创建类的实例对象,通过实例对象实现特定的功能
类的定义
类的组成由1.类名 2. 类的属性(一组数据) 3. 类的方法(要实现的功能)
class 类名():
#属性
a = xx
#方法
def 方法名(self):
pass
# 类的实例化/对象
t = 类名()
# 使用类里面的方法
t.方法名()
# 往类里面添加属性
t.name = "张三"
定义类时发生的事:
1.类在定义时,会产生一个空的名称空间
2.把类内部的所有名字,扔到类的名称空间中
类名会指向类的名称空间, 类名.__dict__
可以查看类名称空间中所有名字
class empty:
pass
# 这是一个空类
class person:
'''定义了一个person类'''
hair = 'black'
# 定义了一个类属性
def say(self,content): # (self参数特殊意义)
# 定义了一个say方法
print(content)
类的修改
通过'' 类名+.
+ 属性/方法'' 的方式对类内部进行修改
.
对指向类内存的名称空间,从而获取名字
class old:
school = 'oldboy'
# 增
old.name = 'tank'
print(old.name) # tank
# 删
del old.name
print(old.name) # 报错,
# 改
old.school = 'oldgirl'
print(old.school) # oldgirl
# 查
print(old.school) # oldgirl
__init__(self)
类构造方法
创建类时,可以手动添加__init__()
方法,这是一个特殊的类实例方法,称为构造方法(或构造函数),
数据的初始化,不需要调用,当创建了一个对象时既自动调用了该方法。
__init__()方法可以包含多个参数,但必须包含一个名为self的参数
且必须是第一个参数
# 注意,如果开发者没有为该类定义任何构造方法,那么 Python 会自动为该类创建一个只包含 self 参数的默认的构造方法。
创建一个名为san的person类对象,调用时自动触发执行了构造方法
class person:
def __init__(self):
print('调用构造方法')
san = person()
# 运行输出
调用构造方法
构造方法可以传入多个参数,self不需要主动传参,self 就是对象本身
谁调用这个对象,self就指向谁。
如果使用了self.变量名,同一个类里面的方法都可以使用。
class person:
def __init__(self,name,age):
print(' "名字是:",name, "年龄为:"')
# 创建张三对象,并传递参数给构造函数
zhangsan = person("张三",20)
# 执行输出为 名字是:张三, 年龄为:20
对象的创建和使用
class语句只能创建一个类,无法创建类的对象,如果想要使用创建好的类,必须手动创建类的对象,这个过程称为类的实例化
类名 + () 调用类产生对象
class person:
school = 'oldbay'
# 若init有其他参数,创建对象时必须传参
def __init__(self,name,age):
print(' "名字是:",name, "年龄为:"')
def student():
pass
# 创建张三对象,并传递参数给构造函数
zhangsan = person("张三",20)
zhagsan.school() # 可以调用属性
zhangsan.student() # 可以调用函数方法
# 执行输出为 名字是:张三, 年龄为:20
名称空间的产生
1.类的名称空间在定义类阶段就已经产生了
2.对象的名称空间,在调用类时产生
调用类时发生的事情
- 首先产生了一个空的对象,产生'对象的名称空间
- 会自动触发
__init__
- 会把对象以及括号内的参数一并传给
__init__
函数
对象添加特征
self 就是对象本身
class old:
def __init__(self,x,y):
print(x,y)
stu = old('nick',18)
# 运行 nick 18
'''方式1'''
stu.name = 'nick' # 对象的赋值方式
print(stu.name)
# nick
'''方法2''' *****
class old:
def __init__(self,x,y):
self.name = x # 在__init__内部添加属性
self.age = y
stu = old('nick',18) # 可以在调用时传入不同参数
print(stu.name) # nick
对象与类的查找顺序
对象 ==> 类 ==> 报错
- 对象属性,若对象本身有,则优先查找对象自己的
- 若对象本身没有,则去类里面找,若类没有,则报错.
对象绑定方法的特殊之处
类内部的函数主要是给对象用的:
- 由类来调用类内部的函数,该函数只是一个普通的函数,需要传入指定数量的参数.
- 由对象来调用称之为对象的绑定方法,不同的对象调用该绑定方法,则会将不同的对象传入该绑定方法中
- 对象的绑定方法是由对象来调用的,特殊之处就是把对象当做第一个参数传入该方法中.
class Old:
school = 'oldboy'
def __init__(self,name,age):
self.name = name
self.age = age
def lenarn (self):
print('请输入密码')
# 1.用类来调用函数,函数有几个参数,需传几个参
Old.lenarn(123) # 请输入密码
# 2.用对象来调用类中函数,不需要传参(会将对象当做self传入)绑定方法.
stu = Old('nick',20)
stu.lenarn() # 请输入密码
对象之间与类的方法功能是一样
一切皆对象
八大数据类型都是类,python中一切皆对象.
self用法
class Dog:
def __init__(self):
print("正在执行构造方法")
# 定义一个jump()实例方法
def jump(self):
print("正在执行jump方法")
python中要求,类方法中(构造方法,实例方法)中至少包含一个参数,但没有规定此函数的名称,约定俗成使用self.
作用:
同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数传给该方法
python会自动绑定类方法的第一个参数指向调用该方法的对象.
对于构造方法来说,self参数(第一个参数)代表该构造方法正在初始化的对象
因此,程序在调用实例方法和构造方法时,不需要为第一个参数传值。
人狗大作战
'''制作一个互相攻击的游戏'''
class people:
def __init__(self,name,aggr,life):
self.name = name
self.aggr = aggr
self.life = life
def skill(self,dog):
if dog.life <= 0:
return True
dog.life -= self.aggr
print(f'''
人{self.name}攻击狗{dog.name}
狗受伤{self.aggr}
狗还剩血量{dog.life}
''')
class dog:
def __init__(self,name,dog_type,aggr,life):
self.name = name
self.dog_type = dog_type
self.aggr = aggr
self.life = life
def skill(self,people):
if people.life <= 0:
return True
people.life -= self.aggr
if people.life <0:
return '''f'
{self.name}狗攻击{people.name}人
人受到{self.aggr}点伤害
游戏结束
'''''
print(f'''
{self.name}狗攻击{people.name}人
人受到{self.aggr}点伤害
人还剩{people.life}血量
''')
p = people('AAA',100,500)
D =dog('旺财','哈士奇',200,700)
while True:
flag = D.skill(p)
if flag:
break
flag = p.skill(D)
if flag:
break