面向对象基础
一、面向对象和面向过程
- 面向过程:
- 优点:复杂问题流程化,进而简单化
- 确定:可扩展性差
- 面向对象:
- 优点:可扩展性高
- 缺点:编写复杂度高于面向过程
二、类与对象
类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体。
那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看。
在现实世界中:先有对象,再有类。
世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念。
也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在。
在程序中:务必保证先定义类,后产生对象。
这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类。
不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象。
-
定义类:
类名() 做的事:实例化产生一个空对象,去调用__init__方法,完成对象的初始化
class关键字 类名:
passclass A: pass
-
产生对象:
对象 = 类名()class A: pass B=A()
-
类:
-
获取类的属性和方法:类.__dict__
class A: pass # B=A() print(A.__dict__) #输出: {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
-
类来调用属性和方法:
-
通过dict来取(复杂,不建议使用)
class A: def __init__(self,name,age): self.name = name self.age = age def change_name(self,new_name): self.name = new_name B = A('ocean',18) print(A.__dict__) print(B.__dict__) print(B.name) A.__dict__['change_name'](B,"haha")#比较麻烦,需要传入对象 print(B.name) # {'__module__': '__main__', '__init__': <function A.__init__ at 0x000001796354B708>, 'change_name': <function A.change_name at 0x000001796354B798>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None} {'name': 'ocean', 'age': 18} ocean haha
-
类名.属性/函数
class A: def __init__(self,name,age): self.name = name self.age = age def change_name(self,new_name): self.name = new_name B = A('ocean',18) A.change_name(B,'haha') print(B.name) print(A.c) # haha 你好
-
-
-
对象:
-
对象获取属性和方法:对象.__dict__
class A: def __init__(self,name,age): self.name = name self.age = age def change_name(self,new_name): self.name = new_name B = A('ocean',18) print(B.__dict__) # {'name': 'ocean', 'age': 18}
-
对象来调用属性和方法:对象.属性/方法
class A: def __init__(self,name,age): self.name = name self.age = age def change_name(self,new_name): self.name = new_name B = A('ocean',18) print(B.name) print(B.age) B.change_name('haha') print(B.name) # ocean 18 haha
-
三、产生对象
对象有:数据属性(变量),方法属性(方法)
3.1对象赋属性:
在对象实例化产生对象的时候,在括号内传入值,会被传入到__init__中
-
方式一:
加入有一个学生类,给他一个名字
stu = Student()
stu.name = 'sb'
class Student: pass stu1 = Student() stu1.name = 'chen' print(stu1.name) # chen
-
方式二:通过__init__方法
class Student: def __init__(self,name,age): self.name = name self.age = age stu = Student('ocera','18') print(stu.name) stu.name = 'dsb' print(stu.name) # ocera dsb
-
方式三:
-
在类中定义该方法,方法上写一些参数
class Student: def __init__(self,name,age): self.name = name self.age = age def change(self,new_name): self.name = new_name stu = Student('ocera','18') print(stu.name) stu.change('dsb') print(stu.name) # ocera dsb
-
-
方式四:用类添加
class Student: pass Student.name = 'st2' stu1 = Student() print(stu1.name) # st2
-
方式五:用函数
class Student: def __init__(self,name,age): self.name = name self.age = age stu = Student('ocera','18') print(stu.name) def change_name(obj,new_name): obj.name = new_name change_name(stu,'dsb') print(stu.name)
-
方式六:用类修改
class Student: def __init__(self, name, age): self.name = name self.age = age def study(self): print(self.name) print('study...') def chang_name(obj, new_name): print('原来的名字是%s' % obj.name) obj.name = new_name print('修改的名字是%s' % obj.name) stu = Student('ocera',18) Student.chang_name(stu,'dsb') print(stu.name) # 原来的名字是ocera 修改的名字是dsb dsb
3.2绑定方法:
- 定义在类的内部
- 对象来调用,会自动把对象传送过来,在方法内部就可以进行修改该对象。
-
强调__init__(初始化方法)
__init__方法
为对象初始化自己独有的特征内部帮我们做了一些事:当我在实例化产生对象的时候,会自动调用__init__方法,完成对象的初始化
强调:
1、该方法内可以有任意的python代码
2、一定不能有返回值3、其他的方法可以有返回值
class Student: def __init__(self,name,age): self.name = name self.age =age def study(self): print(self.name) print("study...") def chang_name(self,new_name): print('原来的名字%s'%self.name) self.name = new_name print("现在的名字%s"% self.name) #类来调用对象的绑定方法(写在类中的函数,没加装饰器, # 有几个参数就需要传入几个参数 #Student.__init__(123,'nick',18),由于没有对象,会报错 #类实例化产生对象,会自动调用__init__完成初始化操作 stu = Student('ocera',18) #对象的绑定方法的特殊之处,会把对象本身当作第一个参数传入 stu.study() # ocera study...
-
python中类内置的特使属性
#python为类内置的特殊属性 类名.__name__# 类的名字(字符串) 类名.__doc__# 类的文档字符串 类名.__base__# 类的第一个父类(在讲继承时会讲) 类名.__bases__# 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__# 类的字典属性,查找所有的属性和方法 类名.__module__# 类定义所在的模块 类名.__class__# 实例对应的类(仅新式类中)
3.3属性的查找顺序:
绑定方法,属性的查找顺序
先从对象自身找--->类中找--->报错
四、一切皆对象
4.1函数也是对象
def test():
print('xxx')
test.name = 'lqz'
print(test.name)
#
lqz
4.2 一切皆对象
#一切皆对象
ll=[1,2]
#对象来调用
ll.append(5)
#类来调用
list.append(ll,5)
五、小练习
# 人狗大战
class Dog:
type_dog = "藏獒"
def __init__(self,name,aggressivity,hp = 100):
self.aggressivity = aggressivity
self.name = name
self.hp = hp
def bite(self,target):
target.hp -= self.aggressivity
print(
"""
狗的品种:%s
狗名:%s
狗的伤害值:%s
人受到的伤害:%s
人剩余的血量:%s
"""%(self.type_dog,self.name,self.aggressivity,self.aggressivity,target.hp)
)
class People:
def __init__(self,name,aggressivity,hp = 100):
self.aggressivity = aggressivity
self.name = name
self.hp = hp
def hit(self,target):
target.hp -= self.aggressivity
print(
"""
人名:%s
人的伤害值:%s
狗受到的伤害:%s
狗剩余的血量:%s
""" % (self.name, self.aggressivity, self.aggressivity, target.hp)
)
people1 = People('sb',20)
dog1 = Dog('sg',10,200)
while people1.hp>0 :
people1.hit(dog1)
dog1.bite(people1)
print("接下来是对战小练习,定制英雄,对战开始")
class Revie:
def __init__(self, name, arrgressivity=10, life_value=100, money=100, arror=3):
self.name = name
self.arrgressivity = arrgressivity
self.life_value = life_value
self.money = money
self.arror = arror
def atrack(self, enemy):
enemy.life_value -= (self.arrgressivity - enemy.arror)
class Gewen:
def __init__(self, name, arrgressivity=10, life_value=100, money=100, arror=3):
self.name = name
self.arrgressivity = arrgressivity
self.life_value = life_value
self.money = money
self.arror = arror
def atrack(self, enemy):
enemy.life_value -= (self.arrgressivity - enemy.arror)
class Weapon:
def __init__(self, price=10, life_value=100, arror=10, arrgv=100):
self.price = price
self.arror = arror
self.life_value = life_value
self.arrgv = arrgv
def update(self, obj):
obj.money -= self.price
obj.life_value += self.life_value
obj.arrgressivity += self.arrgv
obj.arror+=self.arror
def fire(self, obj):
obj.life_value -= 50
p1 = Revie('润文')
p2 = Gewen("盖文")
arm = Weapon()
if p1.money > arm.price:
p1.arm = arm
arm.update(p1)
print(p1.money,p1.life_value,p1.arrgressivity,p1.arror)
print(p2.money,p2.life_value,p2.arrgressivity,p2.arror)
while p1.life_value>0 and p2.life_value>0:
p1.atrack(p2)
print("""
姓名:%s
余额:%s
生命值:%s
攻击力:%s
护甲:%s
"""%(p2.name,p2.money, p2.life_value, p2.arrgressivity, p2.arror))
p2.atrack(p1)
print("""
姓名:%s
余额:%s
生命值:%s
攻击力:%s
护甲:%s
""" % (p1.name, p1.money, p1.life_value, p1.arrgressivity, p1.arror))
p1.arm.fire(p2)
print("""
姓名:%s
余额:%s
生命值:%s
攻击力:%s
护甲:%s
""" % (p2.name, p2.money, p2.life_value, p2.arrgressivity, p2.arror))
p2.atrack(p1)
print("""
姓名:%s
余额:%s
生命值:%s
攻击力:%s
护甲:%s
""" % (p1.name, p1.money, p1.life_value, p1.arrgressivity, p1.arror))