一、面向对象编程
回顾:面向过程编程
是一种之前程序员们设计出来的比较好的编程方法,也是一种编程思想。
核心是过程二字,顾名思义,就是先干什么,再干什么,完成一个事情具有的所有步骤。
优点:复杂的流程简单化,程序化,一步一步拆分,降低开发难度。
缺点:扩展性差, 不容易维护。
主要使用的场景:对扩展性要求不高的,如Linux内核,shell脚本
何为面向对象?
核心是‘对象’二字。
与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界而非流程的模拟,是一种“上帝式”的思维方式。
优点:
1.对于指挥者(程序员)来说,不需要再关心具体步骤
2.扩展性,一个单独的个体的特征或行为发生变化时 不会影响到别人
缺点:
1.程序的复杂度变高,你得需要设计这些对象,注意要避免过度设计得问题
2.程序得执行结果可控性低
二、类和对象
什么是对象:
在现实生活中实实在在存在的,具备自己的特征和行为的事物
反过来说 对象就是 特征和行为(技能)的结合体
什么是类
一堆具备相同特征和行为的事物的抽象概念,不实际存在。
conclusion:
先有类还是先有对象:
生活中:
生活中类怎么来的,是通过对象的特征和行为抽取而来,
所以是先有对象才有了类
编程中:
必须是先有类 才能有对象,因为你必须先告诉程序,你这个对象有什么样的特征和行为
类的作用:用于描述该类的对象具备什么样的特征和行为
补充说明:
站的角度不同,定义出的类是截然不同的;
现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类等;
有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类
三、Python中类和对象的操作
复制代码
class Student:
# 如果每个对象的这个属性都相同 才应该定义到类中 比如所有人的学校都相同
school = "北京大学"
复制代码
复制代码
# 创建对象
# 语法: 在类名后加括号 与调用函数写法相同
# stu = Student()
# # 访问对象的属性
# print(stu.school)
# print(Student.school)
复制代码
复制代码
# 修改属性的值
# stu.school = "清华大学"
# print(stu.school)
#
# # 增加属性
# stu.room_num = "1008"
# print(stu.room_num)
#
# # 删除属性
# del stu.room_num
# print(stu.room_num)
复制代码
复制代码
# 对象 与类的名称空间是独立的
# stu.school = "深圳大学" # 为对象的属性赋予新的值
# print(Student.school) # 类中的属性不会变化
# stu.room_num = "1008" # 为对象增加属性
# # print(Student.room_num) #类中也不会出现新的属性
# print(stu.__dict__)
# print(Student.__dict__)
复制代码
对象的属性查找顺序:
对象自己的名称空间 -> 类的名称空间
四、__init__方法详解
该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值。
__init__称之为初始化函数 它会在创建对象的时候自动执行
创建对象时
1.创建一个空对象
2.执行__init__函数 并且自动传入了这个对象
该函数的作用,就是为对象的属性赋初始值
复制代码
def __init__(self,name,color,age,gender):
print("狗__init__执行了")
print(self)
self.name = name
self.age = age
self.color = color
self.gender = gender
复制代码
复制代码
# 在创建对象时,传入参数
dog1 = Dog("大黄","黄色",2,"female")
dog2 = Dog("二哈","白色",2,"female")
print(dog1.__dict__)
print(dog2.__dict__)
复制代码
注意:
1. 使用场景 需要为每个对象定制不同的属性值
2.__init__在创建对象后自动执行
3.第一个self参数 指的是这个对象本身 不需要手动传值
五、绑定方法
复制代码
class Person:
country = "China"
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def sleep(self):
print("sleeping")def eat(self):
print("eating")
复制代码
复制代码
# p1 = Person("矮根",68,"female")
# p2 = Person("成伟",18,"female")
# 类调用类中函数 与 对象调用的区别
# p1.sleep()
# p2.sleep()
# print(Person.sleep)
# print(p1.sleep)
# 类调用
# Person.sleep(10)
# 对象调用
# p1.sleep()
复制代码
类调用与对象调用的区别
对于类而言 sleep就是一个普通函数
对对象而言 sleep是一个绑定方法
绑定方法是什么?
是对象与类中的某个函数的绑定关系 就像生活中 我们都会吃饭 我吃饭你不会饱
那么吃饭就是我自己的绑定方法
为什么要把函数进行绑定?
因为对象的行为 通常都需要访问这个对象的数据 或是修改这个对象的数据
如果没有对象 直接调用函数是没有意义的 在函数中访问不到对象的数据
所以将对象和函数进行绑定
特殊之处
在使用绑定方法时 不需要关心self参数 会自动将这个对象本身传进来
对象调用绑定方法时 最后执行的还是类中的那个函数
练习题:
模拟一个王者荣耀对砍游戏,两个英雄可以对砍 如果血量小于等于0 就GG,考虑所需的对象和英雄的对象。
复制代码
class Hero:
def __init__(self,hero_type,name,blood,q,w,e):
self.hero_type = hero_type
self.blood = blood
self.name = name
self.q = q
self.w = w
self.e = e
def Q(self,enemy):# 跳起来给你一刀
print('%s 对 %s 释放了Q技能 造成%s点伤害,对方剩余血量%s'
%(self.name,enemy.name,self.q,enemy.blood-self.q))
enemy.blood -=self.q
if enemy.blood <= 0 :
print('Hero %s is GG'%enemy.name)
def W(self,enemy):# 给你一脚
print('%s 对 %s 释放了W技能 造成%s点伤害,对方剩余血量%s'
%(self.name,enemy.name,self.w,enemy.blood-self.w))
enemy.blood -=self.w
if enemy.blood <= 0 :
print('Hero %s is GG'%enemy.name)
def E(self,enemy):# 大宝剑
print('%s 对 %s 释放了Q技能 造成%s点伤害,对方剩余血量%s'
%(self.name,enemy.name,self.e,enemy.blood-self.e))
enemy.blood -= self.e
if enemy.blood <= 0 :
print('Hero %s is GG'%enemy.name)
# 定义英雄的对象
yashe = Hero('战士','亚瑟',200,50,30,100) #q,w,e 50,30,100
daji = Hero('法师','妲己',180,10,30,180) #q,w,e 10,30,180
yashe.E(daji)
daji.W(yashe)
yashe.W(daji)
daji.Q(yashe)
yashe.Q(daji)
复制代码
输出:
复制代码
亚瑟 对 妲己 释放了Q技能 造成100点伤害,对方剩余血量80
妲己 对 亚瑟 释放了W技能 造成30点伤害,对方剩余血量170
亚瑟 对 妲己 释放了W技能 造成30点伤害,对方剩余血量50
妲己 对 亚瑟 释放了Q技能 造成10点伤害,对方剩余血量160
亚瑟 对 妲己 释放了Q技能 造成50点伤害,对方剩余血量0https://www.cnblogs.com/wanlei/p/9830483.html