人生三问
- 什么是对象
- 实实在在存在的具有一定特征和行为的事物就是对象,万物皆对象。
- 什么是类
- 一系列具有相同特征和行为的对象的结合就叫做类。编程中,首先由类,才会有对象。
- 1. 什么是面向对象
面向对象和面向过程都是一种编程的思想,一个在于过程,一个在于对象,面向对象就是把一切的事物都看成
对象,我们需要完成事物的时候就通过对象帮我们完成,而不是像面向过程必须要自己去考虑方方面面来完成这样
事情一样。
- 2. 为什么要用面向对象
大环境:每个公司的业务都是在不断发展的,对于这种现状我们必须要有一个扩展性强的方法。
优点:
1.扩展性强。一切皆对象,一个对象增加属性并不会产生特点大的影响。
2.简化了程序员的操作,我们不必再一步一步去完成事情,而是需要交给对象去完成就可以了
缺点:
1.增加了设计的复杂度。我们要事先设计好合适的对象,避免过度设计。
2.程序的可控性降低。
- 3. 怎么使用面向对象
创建类和对象
- # 定义类,用【class 类名:】 定义一个类
- # 类名的规范:一般大写开头,使用驼峰命名法
- class SHOldboyStudent:
- # 用变量来定义类对象的特征(通常把特征称作属性)
- # 学生会有名字,年龄,性别,学校
- age = '11'
- name = 'egon'
- gender = 'female'
- school = 'HSOldboy'
- # 用函数来定义对象的行为(通常把行为称作方法)
- # 行为可以有多个,每次定义行为的时候都会自动加上一个参数self
- def say_hi(self):
- print('hi, i am boy!')
- def say_hello(self):
- print('hello, i am boy')
-
- # 创建对象,可以通过【类名()】来创建一个对象
- student = SHOldboyStudent()
类的属性
- 注意的点:
- 对象的名称空间和类的名称空间是相对独立的,如果是公共的属性才会放到类中。类中可以没有属性。
- 属性的查找顺序
先从对象的名称空间 =====》类的名称空间。
查看属性(对象和类都可以的):
- # 创建对象,可以通过【类名()】来创建一个对象
- student = SHOldboyStudent()
- # 查看类中的名称空间
- print(SHOldboyStudent.name, SHOldboyStudent.__dict__)
- # 查看对象的名称空间
- print(student.__dict__)
- # 通过对象名称去访问相应的属性
- print(student.name)
- # 结果:
- # egon {'__module__': '__main__', 'age': '11', 'name': 'egon', 'gender': 'female', 'school': 'HSOldboy', 'say_hi': <function SHOldboyStudent.say_hi at 0x037E4F60>, 'say_hello': <function SHOldboyStudent.say_hello at 0x037F8078>, '__dict__': <attribute '__dict__' of 'SHOldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'SHOldboyStudent' objects>, '__doc__': None}
- # {} # 对象的名称空间是空的
- # egon # 但是对象却可以访问到值,为什么呢,因为对于类中的属性而言,对于每个对象都是一样的,所以没有必要保存两份,当对象需要的时候直接去类中查找就是了
增加属性(只能是对象):
- # 增加属性只是增加到了对象中,类中的属性是不会发生改变的
- student = SHOldboyStudent()
- student.height = 15
- print(student.height) # 给对象student增加了一个身高的属性,所以能够访问到
- # print(SHOldboyStudent.height) 这个是会报错的,因为在类中并没有此属性
删除属性(只能是对象)
- # 删除属性只是删除对象中的属性,类中的属性是不会发生改变的
- student = SHOldboyStudent()
- student.height = 15
- print(student.height) # 给对象student增加了一个身高的属性,所以能够访问到
- del student.height
- print(student.height) # 在去查看的时候就会报错了,因为此时height属性已经被删除了
- # print(SHOldboyStudent.height) 这个是会报错的,因为在类中并没有此属性
更改属性(只能是对象)
- # 更改属性, 类中的属性不会发生改变
- student = SHOldboyStudent()
- print(student.name) # egon
- student.name = 'hu'
- print(student.name) # hu
- print(SHOldboyStudent.name) # egon
类的方法
类的特殊方法__init__

- # 定义类,用【class 类名:】 定义一个类
- # 类名的规范:一般大写开头,使用驼峰命名法
- class SHOldboyStudent:
- # 用变量来定义类对象的特征(通常把特征称作属性)
- # 学生会有名字,年龄,性别,学校
- age = '11'
- name = 'egon'
- gender = 'female'
- school = 'HSOldboy'
- # 用函数来定义对象的行为(通常把行为称作方法)
- # 行为可以有多个,每次定义行为的时候都会自动加上一个参数self
- def say_hi(self):
- print('hi, i am boy!')
- def say_hello(self):
- print('hello, i am boy')
指定定义的学生类
- 定义的学生类的问题:
我们在类中定义的公共属性有name,age,gender等,我们想一下,我们的学生都有不同的名字,年龄和性别,但是我们通过上面的类就会出现一样的属性,这显然是不合理的,我们不能定义这些属性,而是应该这每个对象自己去定义这些属性,因此
有了下面这个版本。
改进版本:
- class SHOldboyStudent:
- # 目前这个学生类还没有任何的公共属性
- def say_hi(self):
- print('hi, i am boy!')
- def say_hello(self):
- print('hello, i am boy')
- # 创建一个对象学生一
- stu1 = SHOldboyStudent()
- # 为学生添加属性
- stu1.name = 'egon'
- stu1.age = 11
- stu1.gender = 'female'
-
- # 创建一个对象学生二
- stu2 = SHOldboyStudent()
- # 为学生添加属性
- stu1.name = 'hu'
- stu1.age = 12
- stu1.gender = 'male'
问题二:这样的话虽然说解决了公共属性的问题,但是我们的对象每次创建的时候都要重新去添加属性,而且大部分添加的属性都是一样的,因此我们会想到通过函数去解决这样的问题:
- class SHOldboyStudent:
- # 目前这个学生类还没有任何的公共属性
- def say_hi(self):
- print('hi, i am boy!')
- def say_hello(self):
- print('hello, i am boy')
- def add_attribute(obj, name, age, gender):
- obj.name = name
- obj.age = age
- obj.gender = gender
- # 创建一个对象学生一
- stu1 = SHOldboyStudent()
- # 为学生添加属性
- add_attribute(stu1, 'egon', 11, 'female')
- print(stu1.name)
- # 创建一个对象学生二
- stu2 = SHOldboyStudent()
- # 为学生添加属性
- add_attribute(stu1, 'hu', 11, 'male')
- print(stu1.name)
问题三:这样子我们还需要重新再定义一个函数,然后把创建的对象放进去,很麻烦,此时就该我们的__init__文件发挥作用了
- __init__文件作用
就是为了在创建对象的时候直接调用此函数进行复制,解决我们上面重新定义添加对象属性的问题
注意:
1. 需要为每个对象定制不同的属性值
2. __init__在创建对象的时候自动执行
3. __init__第一个self参数指的就是对象本身,不需要进行传递
- class SHOldboyStudent:
- # 这个init文件
- def __init__(self, name, age, gender): # 参数self就是之前的obj对象本身,此处只不过规范化了而已
- self.name = name
- self.age = age
- self.gender = gender
-
- def say_hi(self):
- print('hi, i am boy!')
- def say_hello(self):
- print('hello, i am boy')
- # 创建一个对象学生一
- stu1 = SHOldboyStudent('egon', 11, 'female') # 这里只需要传递三个对象属性值就可以了,对象的传递已经python已经直接帮我们进行封装了。
- # 创建一个对象学生二
- stu2 = SHOldboyStudent('hu', 11, 'male')
对象与方法的绑定
人生三问
- 绑定方法是什么
绑定方法指的就是对象与方法的一种绑定关系。 - 为什么要用绑定方法
通常对象的行为(也就是类的方法)都需要去访问这个对象的数据,或者去修改这个对象的数据,不去创建对象而直接去调用类的方法是没有意义的,所以将对象和和函数进行绑定。 - 怎么使用绑定方法
在类中python本身就已经给我们进行绑定方法了,也就是通过self参数直接帮我们将对象本身传递进去。
1. 类去调用方法
- # 类调用方法就相当于是使用普通函数一样,该传什么值就传什么值
class SHOldboyStudent: - # 目前这个学生类还没有任何的公共属性
- def __init__(self, name, age, gender):
- self.name = name
- self.age = age
- self.gender = gender
- def say_hello(self):
- print(self)
- print('hello, i am boy')
- # 1.不进行传值,会报错
- SHOldboyStudent.say_hello(111)
2. 对象去调用类的方法
- class SHOldboyStudent:
- # 目前这个学生类还没有任何的公共属性
- def __init__(self, name, age, gender):
- self.name = name
- self.age = age
- self.gender = gender
- def say_hello(self):
- print(self)
- print('hello, i am boy')
- # 1.可以直接进行传值,因为对象和方法已经进行绑定了
- student = SHOldboyStudent('egon', 11, 'male')
- student.say_hello()
小案例:
创建一个英雄类,创建两个英雄进行互砍
- class Hero:
- def __init__(self, blood, name, hero_type, q, w, e):
- self.blood = blood # 血量
- self.name = name # 名字
- self.hero_type = hero_type # 英雄类型
- self.q = q # q技能伤害
- self.w = w # w技能伤害
- self.e = e # e技能伤害
-
- def hurt(self, enemy, skill):
- print('{name}向{enemy}释放了{skill}技能,造成伤害{hurt},敌军{enemy}剩余血量{blood}'.format(
- name=self.name,
- enemy=enemy.name,
- skill=skill,
- hurt='self.%s' % skill,
- blood=0 if enemy.blood - self.q < 0 else enemy.blood - self.q
- ))
- enemy.blood = enemy.blood - self.q
- if enemy.blood < 0:
- print('敌军{enemy}阵亡'.format(enemy=enemy.name))
- # 创建两个英雄对象
- yasuo = Hero(200, 'yasuo', 'zhanshi', 50, 100, 150)
- huangzi = Hero(200, 'huangzi', 'zhanshi', 60, 80, 180)
- yasuo.hurt(huangzi, 'q')
- yasuo.hurt(huangzi, 'e')