以下是网上关于面向对象的解释:
面向对象技术简介
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
总的来说,类就是一个分组、一个分类,同一个类里的对象可以用这个类的特性、属性来描述,类里的对象具有共同的特性。
同样是定义怪兽群体,以下分别采用面向过程、面向对象的方式来编写。
以下为面向过程
user1 = {'name':'tom','hp':100}
user2 = {'name':'herry','hp':200}
def print_role(rolename):
print('name is %s,hp is %s' %(rolename['name'],rolename['hp']))
print(print_role(user1))
以上将user1 和user 2 打印时都是直接调用print_role()方法,从上到下依次执行,要提前定义好user
类的创建
如果使用面向对象编程,如下
class Player(): # 定义一个类 大写字母开头
def __init__(self,name,hp):
self.name = name # 变量被称作属性
self.hp = hp # self 代表类的实例化本身
def print_role(self): # 定义一个方法
print('%s:%s' %(self.name,self.hp))
user1 = Player('tom',100) # 类的实例化
user2 = Player('jerry',300)
user1.print_role()
user2.print_role()
print(user1.hp) # 获取对象user1的属性
print(user2.hp) # 获取对象user2的属性
如上,使用面向对象编程之后无需提前单独定义某个对象。在Player()类中定义了类共有的属性,如:def init(self,name,hp): 这个self 是指类的实例化对象本身,所以在类中定义的属性、方法时不能少了“self"。
再通过对类实例化创建一个对象,这个对象就拥有了self的属性、方法,使用如下:
user1 = Player('tom',100) # 类的实例化
user2 = Player('jerry',300)
user1.print_role()
user2.print_role()
print(user1.hp) # 获取对象user1的属性
print(user2.hp) # 获取对象user2的属性
增加类的属性
增加类的属性需要在定义类时,init(self, attribute_1,attribute_2,…),如下增加‘occu’ 职业属性
class Player():
def __init__(self,name,hp,occu):
self.name = name # 变量被称作属性
self.hp = hp # self 代表类的实例化本身
self.occu = occu # 增加的属性
# 在对类进行实例化的时候也相应带上对应的参数
user1 = Player('tom',100,'war')
user2 = Player('jerry',300,'master')
改变对象的属性内容
需要对已经实例化的对象属性的内容进行改变时可以在类定义一个方法,比如修改以上示例类的name,可在Player 类定义一个update()的方法来改变属性赋值,如下
class Player(): # 定义一个类 大写字母开头
def __init__(self,name,hp,occu):
self.__name = name # 变量被称作属性, __ 表示不能被外部修改,变量不会被实例访问到
self.hp = hp # self 代表类的实例化本身
self.occu = occu
def print_role(self): # 定义一个方法
print('%s:%s' %(self.name,self.hp))
def updateName(self,newname):
self.name = newname
user1.updateName('wilon') # user1的name 将会从“wa r” 改成“wilon”
类的私有变量
上一节谈到修改类的属性,那是否可以通过直接通过赋值改变属性的内容呢,如下
user1.name = 'wilon'
是可以的,但是如果类里定义的变量是私有变量的时候通过以上直接赋值就无法修改属性。私有变量是在定义的时候在变量名前加上‘–’,如下
class Player(): # 定义一个类 大写字母开头
def __init__(self,name,hp,occu):
self.__name = name # 变量被称作属性, __ 表示不能被外部修改,变量不会被实例访问到
self.hp = hp # self 代表类的实例化本身
self.occu = occu
类的继承与多态
class Monstor():
'定义怪物类,为父类'
def __init__(self,hp=200):
self.hp = hp
def run(self):
print('移动到某个位置')
def whoami(self):
print('这是父类的方法')
class Animals(Monstor): # 继承Monstor 父类
'普通怪物'
# def __init__(self,hp = 10):
# self.hp = hp
def __init__(self,hp = 1000):
super().__init__(hp)
class Boss(Monstor): # 继承Monstor 父类
'Boss类怪物'
def __init__(self,hp = 200):
super().__init__(hp)
def whoami(self):
print('这是子类的方法')
a1 = Monstor(100)
print(a1.hp)
print(a1.run())
a2 = Animals(10)
print(a2.hp)
print(a2.run())
a3 = Boss(40)
print(a3.hp)
print(a3.run())
a1.whoami()
a3.whoami() # 在实例化子类的时候就会把父类的同名方法给覆盖掉
以下是输出:
100
移动到某个位置
None
10
移动到某个位置
None
40
移动到某个位置
None
这是父类的方法
这是子类的方法
以上创建了1个Monstor 父类和两个继承于父类的子类(Animals、Boss)。总结以下问题:
- Animals、Boss 在子类里没有定义run()方法,但是实例化后的a2、a3对象可使用父类的run()
- 在 Animals、Boss 子类里需要重复引用父类的属性’hp’,但是在子类不需要重复定义,因为当大量被引用的时候消耗计算机资源,可使用‘super().init(hp)’ 作用是如果在父类进行里初始化,那在子类不用重复进行初始化。
class Boss(Monstor):
'Boss类怪物'
def __init__(self,hp = 200):
super().__init__(hp)
- 如果子类和父类定义的方法名称一样,在实例化子类的时候就会把父类的同名方法给覆盖掉,不会继承父类的同名方法。在该种情况下运行起来会有不同的状态,也就是多态
判断子类和父类之间的继承关系
- 使用type 可以看到对象的类
print('a1的类型是 %s' % type(a1))
print('a2的类型是 %s' % type(a2))
print('a3的类型是 %s' % type(a3))
a1的类型是 <class '__main__.Monstor'>
a2的类型是 <class '__main__.Animals'>
a3的类型是 <class '__main__.Boss'>
- 使用isinstance()可以判断某对象跟类的继承关系
print(isinstance(a1,Monstor)) # a 是否继承与Monsto
print(isinstance(a2,Monstor))
print(isinstance(a3,Animals))
True
True
False
PS : 所有的类都继承于Object类
4万+

被折叠的 条评论
为什么被折叠?



