面向对象初识
初始面向对象
- python中一切皆对象
- 面向过程和面向对象得区别:
- 面向过程:想要一个结果 写代码 实现结果
- 面向对象:有哪些角色,角色的属性和技能 ,角色之间的交互关系
- 面向对象适用场景:
- 复杂的,拥有开放式结局的程序,比较适合使用面向对象
- 游戏(人物多,技能多)
- 购物
- 复杂的,拥有开放式结局的程序,比较适合使用面向对象
面向对象基础语法
-
自己了解:类相当于一个教室,教师里面有桌子,椅子。学生相当于对象(实例)可以有很多学生进行使用。也就是(铁打的类,流水的对象)
-
类:这个类有什么属性,用什么方法,大致什么样子,不能知道具体属性的对应值
-
对象:之前所有的属性值就都明确
-
先定义模子(类)用来描述一类事物,这类事物具有相同的属性和动作
-
__init__
这个名字,不能改变,所有的在具体人物出现之后拥有的属性,都可以写在__init__
里 -
调用类时会自动调用
__init__
类 -
person是类,x1就是对象,x1=Person()的过程就是通过类获取一个对象的过程称为实例化
类和对象之间的关系
- 类是一个大范围,是一个模子,它约束了事物有哪些属性,但不能约束具体的值
- 对象是一个具体的内容 ,是模子的产物,它遵循了类的约束,同时给属性赋上了具体的值
- 类有一个空间存储的是定义在class中的所有名字
- 每一个对象又拥有自己的空间,通过 对象名.
__dict__
就可以查看对象的属性和值,以字典的形式返回回来
面向对象的增删改查
class Person: #Person类名可以加()也可以不加
def __init__(self,name,sex,job,hp,weapon,ad):#必须叫__init__这个名字,不能改变,所有的在具体人物出现之后拥有的属性,都可以写在这里
print('_'*20)
self.name=name
self.sex=sex
self.job=job
self.level=0
self.hp=hp
self.weapon=weapon
self.ad=ad
print('*'*20)
print(self,self.__dict__)
x1=Person('xiaotong','女','学生',40000,'神笔',10) #调用类 # Person()会自动调用类中的__init__方法
print(x1,x1.__dict__)
#属性值的查看
print(x1.name) #print(x1,x1.__dict__['name'])
#属性的修改
x1.name='xiaotongxiaokeai'
print(x1.name)
#属性的增加
x1.money=100
print(x1,x1.__dict__)
#属性的删除
del x1.money
print(x1,x1.__dict__)
# <__main__.Person object at 0x000002777852A6A0> {'name': 'xiaotong', 'sex': '女', 'job': '学生', 'level': '0', 'hp': '1000', 'weapon': '神笔', 'ad': '10'}
# <__main__.Person object at 0x000002777852A6A0> {'name': 'xiaotong', 'sex': '女', 'job': '学生', 'level': '0', 'hp': '1000', 'weapon': '神笔', 'ad': '10'}
# xiaotong
# xiaotongxiaokeai
# <__main__.Person object at 0x000001D2E044A6A0> {'name': 'xiaotongxiaokeai', 'sex': '女', 'job': '学生', 'level': 0, 'hp': 40000, 'weapon': '神笔', 'ad': 10, 'money': 100}
# <__main__.Person object at 0x000001D2E044A6A0> {'name': 'xiaotongxiaokeai', 'sex': '女', 'job': '学生', 'level': 0, 'hp': 40000, 'weapon': '神笔', 'ad': 10}
实例化对象经历的步骤
- 类名()之后的第一件事:开辟一块内存空间
- 调用
__init__
把空间的内存地址作为self参数传递函数内 - 所有的这一个对象使用的属性都要和self关联起来
- 执行完init的逻辑后,self变量会自动的被返回到调用的地方,也就是发生实例化的地方
- selef.name=name称为对象的属性,也称实例变量
- 自己理解:在调用类的时候开辟一块空间,将这块空间的内存地址作为self传入
__init__
中,在执行init方法时将与对象相关的属性存入self内存地址中(self.name=name),在执行完init方法后会自动将存入self的属性以列表的形式返回到发生实例化的地方。 - 方法:定义在类里面的函数,并且还带有self参数
- 实例变量:self.名字
小练习
游戏
class Person:
def __init__(self,name,sex,job,hp,weapon,ad):
self.name=name
self.sex=sex
self.job=job
self.level=0
self.hp=hp
self.weapon=weapon
self.ad=ad
def shen(self,dog):
if dog.blood>=self.ad:
dog.blood-=self.ad
else:
dog.blood=0
print(f'{self.name}使用{self.weapon}打掉了{dog.name}的{self.ad}点血,{dog.name}现在还有{dog.blood}滴血!')
x1=Person('xiaotong','女','学生',40000,'神笔',10)
print(x1.__dict__)
# proper :属性
# name: 姓名
# variety:品种
# blood: 血量
# atk: 攻击力
class Dog:
def __init__(self,proper,name,variety,blood,atk):
self.proper=proper
self.name=name
self.variety=variety
self.blood=blood
self.atk=atk
def bite(self,user):
if user.hp>=self.atk:
user.hp-=self.atk
else:
user.hp=0
print(f'{self.name}使用{self.proper},干掉了{user.name}的{self.atk}滴血,{user.name}现在还有{user.hp}滴血!')
xiaobai=Dog('咬','xiaobai','萨摩耶',250,20)
print(xiaobai.__dict__)
x1.shen(xiaobai)
xiaobai.bite(x1)
# {'name': 'xiaotong', 'sex': '女', 'job': '学生', 'level': 0, 'hp': 40000, 'weapon': '神笔', 'ad': 10}
# {'proper': '咬', 'name': 'xiaobai', 'variety': '萨摩耶', 'blood': 250, 'atk': 20}
# xiaotong使用神笔打掉了xiaobai的10点血,xiaobai现在还有240滴血!
# xiaobai使用咬,干掉了xiaotong的20滴血,xiaotong现在还有39980滴血!
计算圆的面积和周长
class Round:
def __init__(self,radius):
self.radius=radius
def area(self): #求圆的面积
s= 3.14*self.radius**2
return s
def perimeter(self): #求圆形的周长
c=3.14*self.radius*2
return c
rou=Round(5)
print(rou.__dict__)
print(rou.area())
print(round(rou.perimeter(),1)) #round保留浮点数小数的位数
rou1=Round(10)
print(rou1.__dict__)
print(rou1.area())
print(round(rou1.perimeter(),1))
#{'radius': 5}
# 78.5
# 31.4
# {'radius': 10}
# 314.0
# 62.8
定义一个用户类,用户名和密码时这个类的属性,分别有不同的用户名和密码
- 登陆成功之后才创建用户对象
- 设计一个方法用来修改密码
class User:
def __init__(self):
self.alist=[{'username':'xiaotong','password':111},{'username':'wangminmin','password':222}]
def login(self):
username=input('请输入用户名:')
password=input('请输入密码:')
for i in self.alist:
if username == i['username'] and int(password)==i['password']:
return '登陆成功'
else:
return '登陆失败'
def amend(self):
s1=int(input('请输入之前密码:'))
for i in self.alist:
if s1==i['password']:
s2=input('请输入新密码:')
i['password']=s2
print('密码修改成功!')
print(self.__dict__)
else:
print('输入错误!')
def ccc(self,pd):
while True:
ss='''
1.退出
2.修改密码
'''
print(ss)
xx=input('请输入选项:')
if xx == '1':
break
elif xx=='2':
pd()
user=User()
s=user.login()
print(s)
if s=='登陆成功':
s = user.ccc(user.amend)
面向对象的命名空间
-
python中一切皆对象,对象的类型就是类
-
类型:str,list,float,dict,tuple,set-----类(内置的数据类型,内置的类)
-
所有的对象都有一个类型,class A实例出来的对象的类型就是A类
b=[1,2,3] print(type(b)) class A: pass a=A() print(type(a)) # <class 'list'> # <class '__main__.A'>
-
123的类型就是int/float
-
'dfghjk'的类型就是str
-
{}的类型就是dict
-
def func的数据类型就是function
-
minmin=A()的类型就是A
-
xiaotong=B()的类型就是B
面向对象的命名空间
-
类中的变量是静态变量,对象中的变量只属于对象本身
-
当使用对象名调用某一个属性的时候,会优先在自己的空间中寻找,找不到再去对应的类中寻找
-
如果自己没有没有就使用类的,如果类没有就报错
-
对于类来说,所有的对象都是可以读取的,并且读取的都是同一份变量
class A: b='中国' #静态变量/静态属性 --- 存储在类的命名空间 c=[1,2,3] def __init__(self,name,b): #绑定方法存储在1类的命名空间里 self.name=name self.b=b def func(self):pass def func1(self):pass #绑定方法存储在1类的命名空间里 def func2(self):pass a=A('minmin','山西') #实例化对象的时候会开辟一个空间,里面有个类指针(指向A类的内存地址) # 在进行加载的时候会先在自己的空间中寻找,如果没有则通过类指针在A类的空间中寻找 print(A.b) print(a.b) a.func() #==A.func(a) # 中国 # 山西 # <function A.func at 0x0000017042B21B70>
-
静态变量的用处
- 如果有一个对象,是所有的对象共享的值,那么这个变量应该被定义为静态变量
- 所有和静态变量相关的增删改查都应该使用类名来处理,而不应该使用对象名直接修改静态变量
-
小练习
- 实现一个类,能够自动统计这个类实例化了多少个对象
class A: count=0 def __init__(self): A.count+=1 a=A() b=A() c=A() print(a.count)