Class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
Object 对象
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性。
Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
使用class定义类,可以提供一个可选的父类或者基类,如果没有合适的基类,那就使用object作为基类,也可以不写。新式类写法:class FooClass (object);就旧式类写法:
class Role(object): #定义一个类, class是定义类的语法,Role是类名,(object)是新式类的写法
def __init__(self,name,role,weapon,life_value=100,money=15000):
#当一个类实例化时,_init_()方法会自动执行,该方法目的是对实例初始化工作。
# 同样通过创建自己的_init_()方法,可以覆盖默认的_init_()方法
self.name = name #__init__中的第一个参数self,和这里的self都 是什么意思? 看下面解释
self.role = role
self.weapon = weapon
self.life_value = life_value
self.money = money def shot(self,name):
print("shooting...%s"%name) def got_shot(self):
print("ah...,I got shot...") def buy_gun(self, gun_name):
print("just bought %s" % gun_name) def __del__(self): ##析构函数
print("it is over") r1 = Role('Alex', 'police', 'AK47')
#生成一个角色,Role('Alex', 'police', 'AK47')为实例化的对象地址,把对象地址传给r1
#也可以通过Role('Alex', 'police', 'AK47').shot('paul')调用
r1.shot("paul")
#>>>shooting...paul r2 = Role('Jack', 'terrorist', 'B22') #生成一个角色,此时self 相当于 r2 , Role(r1,'Alex','police','AK47’)
r2.got_shot()
#>>>ah...,I got shot...
上面的这个__init__()叫做初始化方法(或构造方法), 在类被调用时,这个方法(虽然它是函数形式,但在类中就不叫函数了,叫方法)会自动执行,进行一些初始化的动作。__del__为析构函数,在实例释放,销毁时候被执行,常用语一些收尾工作,比如关闭数据库连接或者打开临时文件。我们这里写的__init__(self,name,role,weapon,life_value=100,money=15000)就是要在创建一个角色时给它设置这些属性,那么这第一个参数self是干毛用的呢?
self为实例本身,用于关联调用类的属性和方法。
封装,其实就是使用构造方法将内容封装到某个具体对象中,然后通过对象直接或者self间接获取被封装的内容。
类属性和实例属性
- 类体中、所有函数之外:此范围定义的变量,称为类属性或类变量;用于存储实例共有的属性,节省开销
- 类体中,所以函数内部:以“self.变量名”的方式定义的变量,称为实例属性或实例变量;
- 类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量。
实例变量只能通过对象名访问,无法通过类名访问。
通过类名修改类变量,会作用到所有的实例化对象。通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量
class Person(object):
county='CN'
def __init__(self,name,age):
self.name = name
self.role = age def shot(self,name):
print("shooting...%s"%name) def got_shot(self):
print("ah...,I got shot...") print(Person.county) ##获取类变量
#>>>CN
P1=Person('PAUL','22')
print(P1.county) ##获取类变量
#>>>CN
P1.county='HK' ##并不是修改类变量,通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量
print(P1.county) ##获取新加的实例变量
#>>>HK
P2=Person('EVA','23')
print(P2.county) ##获取类变量
#>>>CN
Person.county='US' ##通过类名修改类变量,会作用到所有的实例化对象
##类中,实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因。
print(P1.county) ##获取新加的实例变量
#>>>HK
print(P2.county) ##获取类变量
#>>>US
P3=Person('kate','25')
print(P3.county)获取类变量
#>>>US
值得一提的是:除了可以通过类名访问类变量之外,还可以动态地为类和对象添加类变量
class Person(object):
county='CN'
def __init__(self,name,age):
self.name = name
self.role = age def shot(self,name):
print("shooting...%s"%name) def got_shot(self):
print("ah...,I got shot...") Person.job='IT'
P1=Person("PAUL",22)
print(P1.job)
#>>>IT
类方法和实例方法及静态方法
类方法:在方法前面加上@classmethod 这样的方法称为类方法,最少也要包含一个参数,只不过类方法中通常将其命名为 cls。调用类方法时,无需显式为 cls 参数传参
类方法可以修改类属性的值。类方法只能访问类变量,不能访问实例变量。
实例方法:带有self的都是实例方法。
静态方法:实际和类没有关系了,静态方法没有类似 self、cls 这样的特殊参数,类的静态方法中无法调用任何类属性和类方法。一般会完成和类对象也和实例对象没有关联的基本功能,如一些打印功能。
class Person(object):
county='CN'
def __init__(self,name,age):
self.name = name
self.role = age def got_shot(self):
print("ah...,I got shot...") @classmethod
def info(cls):
print("正在调用类方法") ##通过类方法修改类变量
Person.county='UK' @staticmethod
def msg(msg):
print('静态方法调用 %s'%msg) #####实例方法
P1=Person("PAUL",22)
P1.got_shot()###类对象直接调用
#>>>ah...,I got shot..
Person.got_shot(P1)##类名调用实例方法,但此方式需要手动给 self 参数传值
#>>>ah...,I got shot.. #####类方法
Person.info() ##使用类名直接调用类方法
#>>>正在调用类方法
P1.info()####使用类对象调用类方法
#>>>正在调用类方法
print(P1.county)
#>>>UK ####静态方法
Person.msg('ok')##使用类名直接调用类方法
#>>>静态方法调用 ok
P1.msg('ok')####使用类对象调用类方法
#>>>静态方法调用 ok
私有方法和变量
无论是私有类变量和方法还是私有实例变量和方法,类外都不能直接访问,只能在类内访问。
class Person(object):
county='CN'
__salary=100
def __init__(self,name,role,age):
self.name = name
self.role = role
self.__age = age def got_shot(self):
print("ah...,I got shot...") def __msg(self):
print('这是私有实例方法') def get_salary(self):
print(self.__salary)
self.__msg() P1=Person("paul",'IT','22')
P1.get_salary()
#>>>100
#>>>这是私有实例方法