面向对象技术简介
- 类(class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 实例变量:定义在方法中的变量,只作用于当前实例的类。
- 继承:即一个派生类(derivedclass)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
类
类是具有相同属性和技能的一类事物,如:人类的通性,即每个人都具有的
语法:
class Objectname: """ 注释 """ variable_name = variable_value # 这里的变量是该类线所有成员都具有的,通用的 # 这里的变量称为静态变量或静态字段 def __init__(self): pass def functuion(self): pass
类名的查看和调用:
1.类名查看类中所有的变量(字段),方法(函数):Objectname.__dict__
2.类名对静态变量(静态字段)进行操作 最好不要通过__dict__这个字典进行操作
2.1通过类名.__dict__ 不建议!!!通过这个方法1.查询类里面所有的变量 Person.__dict__
2.(增删改)查询单个变量 不要用Person.__dict__
2.2 通过类名.变量名 常用!!!
3.类名对动态方法(函数)进行操作 3.1 通过类名.__dict__ 不建议!!!通过这个方法 3.2 类名.方法名class Person: ''' 此类是构建人类 ''' level = '高级动物' mind = '有思想' language = '语言' def __init__(self): pass def work(self): print('开始工作了!!!!') def eat(self): pass# print(Person.__dict__['mind']) # 可以查值# Person.__dict__['create'] = '有创造力' # 不能增加值# del Person.__dict__['mind'] # 不能删除值# Person.__dict__['mind'] = '行尸走肉' # 不能更改值# print(Person.__dict__)# print(Person.mind) # 可查询# print(Person.language) #可查询# Person.create = '有创造力' # 可增加# del Person.mind # 可删除# Person.mind = '行尸走肉'# print(Person.mind)# print(Person.__dict__)# Person.work(111)
类对象
类对象支持两种操作:属性引用和实例化。
属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name。 类对象创建后,类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:class MyClass: """一个简单的类实例""" i = 12345 def f(self): return 'hello world' # 实例化类x = MyClass() # x是抽象的对象, MyClass()是实例化 # 访问类的属性和方法print("MyClass 类的属性 i 为:", x.i)print("MyClass 类的方法 f 输出为:", x.f())
以上创建了一个新的类实例并将该对象赋给局部变量x,x为空的对象。执行以上程序输出结果为
MyClass 类的属性 i 为: 12345MyClass 类的方法 f 输出为: hello world
很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为__init__()的特殊方法(构造方法),像下面这样:
def __init__(self): self.data = []
类定义了 init() 方法的话,类的实例化操作会自动调用__init__()方法。所以在下例中,可以这样创建一个新的实例
x = MyClass()
当然, init() 方法可以有参数,参数通过__init__()传递到类的实例化操作上。例如:
class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.i = imagpartx = Complex(3.0, -4.5)print(x.r, x.i) # 输出结果:3.0 -4.5
self代表类的实例,而非类
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称,按照惯例它的名称是 self。 self是对象的空间地址class Test: def prt(self): print(self) print(self.__class__) t = Test()t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x100771878>__main__.Test
从执行结果可以很明显的看出,self代表的是类的实例,代表当前对象的地址,而self.class 则指向类。
self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的:class Test: def prt(runoob): print(runoob) print(runoob.__class__) t = Test()t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x100771878>__main__.Test
类的方法
在类地内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
#类定义class people: #定义基本属性 name = '' age = 0 #定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0 #定义构造方法 def __init__(self,n,a,w): self.name = n self.age = a self.__weight = w def speak(self): print("%s 说: 我 %d 岁。" %(self.name,self.age)) # 实例化类p = people('runoob',10,30)p.speak()
执行以上程序输出结果为:
runoob 说: 我 10 岁。
实例化对象
用下面一段代码
class Person: ''' 此类是构建人类 ''' level = '高级动物' mind = '有思想' language = '语言' def __init__(self,name,age,sex,area,hobby): # 构造方法 self.name = name # slef.name name 是对象属性 self.age = age self.sex = sex self.area = area self.hobby = hobby def work(self,eye): self.eye = eye print('开始工作了!!!!') def eat(self): pass aduan = Person('啊段',18,'男','河北邯郸','非女')
aduan = Person('啊段',18,'男','河北邯郸','非女') 这个过程叫做实例化对象
对象相对于其他的对象具有个性,这个个性化的过程就是实例化对象 1,产生一个对象空间,包含内的指针,返回给self空间内存地址 2,自动执行类中的__init__方法,并将空的对象空间传给self,剩下的值传给相应形参 3,执行init方法,给对象封装属性,并将完善好的这个对象返回给 类名()对象的属性:
1,查找对象中的所有属性 2,对象操作对象中属性. 3,对象操作类中的静态变量(静态字段). 只能查询不能增删改.# 1,查找对象中的所有属性# aduan = Person('啊段',18,'男','河北邯郸','非女')# print(aduan.__dict__)# aduan = Person('啊段',18,'男','河北邯郸','非女')# aying = Person('啊颖',17,'女','河北衡水','开车...') #2, 对象操作对象中属性.# aduan = Person('啊段',18,'男','河北邯郸','非女')# print(aduan.name) # 查# aduan.job = 'student' # 增# del aduan.age # 删# aduan.sex = 'laddyboy'# print(aduan.__dict__) #3,对象操作类中的静态变量(静态字段). 只能查询不能增删改.# aduan = Person('啊段',18,'男','河北邯郸','非女')# print(aduan.level) # 查 类中的静态字段# aduan.level = '中等动物' # 对象中设置新属性,而不是改变类中的level# print(aduan.level)# del aduan.level# print(Person.__dict__)
4.对象执行类中的方法
aying = Person('啊颖',17,'女','河北衡水','开车...')print(aying)aying.work('大眼睛')print(aying.__dict__)# 1 self 位置参数, 默认接受的是对象空间,约定俗成叫self.# 2 在类的非__init__方法中,也可以给对象添加一些属性,前提必须先执行这个方法.
类的名称空间,对象名称空间
类的名称空间:在执行类是,在内存空间中创建一个存放类的内存空间 对象名称空间:在实例化对象过程中,会在内存空间中创建一个存放对象属性的内存空间,和类的名称空间独立,同过指正联系,无论创建多少对象,都是开辟独立的内存空间,各个对象之间不能互相查找,干扰查询顺序
对象的查询顺序:先从对象空间去找,对象的空间没有此变量或者方法,通过对象中的类对象指针去类中寻找. 类的查询顺序: 直接从类本身找.# job1 = 'teacher'# class A:# home = '老男孩教育'# name = '武大'# def __init__(self, name, age):# self.name = name# self.age = age# def job(self):# print('我在开车.....')# 查询顺序# 对象的查询顺序:先从对象空间去找,对象的空间没有此变量或者方法,通过对象中的类对象指针去类中寻找.# obj1 = A('oldboy',1000)# obj1 = A('oldboy',1000)# obj1 = A('oldboy',1000)# obj1 = A('oldboy',1000)# print(obj1.name)# print(obj1.job)# print(obj1.home)# 类的查询顺序: 直接从类本身找.# print(A.name)# 对象的问题# 无论创建多少对象,都是开辟独立的空间,各个对象之间不能互相查找,干扰.# obj1 = A('oldboy',1000)# obj2 = A('alex',10000)# import girldriver# girldriver.func()
组合: 给一个类的对象,封装一个属性,这个属性是另一个类的对象.
class Game_role: def __init__(self, name, ad, hp): self.name = name self.ad = ad self.hp = hp def attack(self,obj1): obj1.hp = obj1.hp - self.ad print('%s攻击%s,%s掉了%s血,还剩%s血'%(self.name,obj1.name,obj1.name,self.ad,obj1.hp)) def package_weapon(self,wea): self.weapon = weaclass Sword: def __init__(self,name,ad): self.name = name self.ad = ad def fight(self,p1,p2): p2.hp = p2.hp - self.ad print('%s 用 %s 砍了 %s一刀,%s 还剩%s血' %(p1.name,self.name,p2.name,p2.name,p2.hp))# aduan = Game_role('啊段', 10, 100)# ts = Game_role('泰森', 120, 300)# Slaughter_knife = Sword('杀猪刀',200)# 这么写不好,动作的发起人是人而不是刀本身# Slaughter_knife.fight(aduan,ts)# 下面是符合逻辑的# aduan.package_weapon(Slaughter_knife) # 给aduan 这个对象封装了一个weapon属性这个属性值为Slaughter_knife# aduan.weapon.fight(aduan,ts)# ts.attack(aduan)# print(aduan.weapon)# print(aduan.weapon.name)# aduan.weapon.fight(aduan,ts)