面向对象技术简介
- 类(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 为: 12345
MyClass 类的方法 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 = imagpart
x = 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 = wea
class 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)