python是完全面向对象的程序设计语言。面向对象思想解决问题的方式是模拟人认识世界的思维方式,把与问题相关的数据提取出来,将具体相同属性的事物抽象为“类”,设计出“类”的方法,程序执行时,将“类”实例化为“对象”,调用“类”的方法解决问题。
类的定义
类(class):具有相同属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法
class 类名:
属性定义 #变量定义
方法定义 #函数定义
class person:
name = 'lin' #类属性
age = '30'
def sayhi(self): #方法
print('hello,how are you?')
print(person.name)
print(person.age)#类属性:直接通过类名引用
p = person()#对象
p.sayhi()
属性
python属性有两种:实例属性、类属性
实例属性
实例属性时实例对象的属性,两种方法可以定义。
一、在类外显示定义
class person:
name = 'lin' #类属性
p = person()#对象
p.age = 12 # 实例属性age在类外定义
print(p.name)
print(p.age)
print(person.name)
print(person.age)#错误,实例属性是实例对象特有的
二、在类中,使用构造函数__init__定义,定义是要加前缀self
class person:
name = 'lin' #类属性
def __init__(self,age):#构造函数,在实例对象中自动调用
self.age = age
p = person(12)#对象
print(p.name)
print(p.age)
print(person.name)
print(person.age)#错误,实例属性是实例对象特有的
类属性
类属性是在类中、方法外定义的属性,分为公有属性和私有属性(属性名前有两个下划线“__”)。
访问类的属性
公有属性:为类的所有对象共有,在类外可通过类名和实例对象名访问。通过对象名访问类属性,实例属性会屏蔽掉类属性,给出实例属性的数值。通过类名访问类属性,给出类属性的数值。
私有属性不能在类外通过类名和实例对象名访问。
class person:
name = 'lin' #公有属性
__age = 12 #私有属性
p = person()
print(p.name) #通过实例对象名访问
print(person.name)#通过类名访问
print(p.__age) #错误,不能在类外通过实例对象名访问
print(person.__age)#错误,不能在类外通过类名访问
修改和删除类属性
类属性修改必须通过实例对象,类属性的修改会产生一个同名的实力副本,类属性修改的实质是对实例属性的修改,不会影响到类属性数值。
当实例属性被删除后,通过实例属性访问的数值就是类属性的数值。
class person:
name = 'lin'
print(person.name)
p = person()
p.name = 'zhu'
print(p.name)
print(person.name)
del p.name
print(p.name)
方法
python方法有三种:对象方法(具有self参数)、类方法(使用@classmethod,具有cls参数)、静态方法(使用@staticmethod,不需要参数)
对象方法
对象方法分为公有方法和私有方法(方法名前有两个下划线“__”)。对象方法和普通参数的区别:必须有一个额外的第一个参数名称为self,当对象调用该方法时,python就将对象作为第一个参数传给self
公有方法:通过对象名调用
class person():
def sayhi(self):#公有方法
print("hello,how are you ?")
p = person() #调用
p.sayhi()
私有方法:只能在对象的共有方法中使用self调用
class person():
def __sayhi(self):
print("hello,how are you ?")
def output(self):
self.__sayhi()
p = person()
p.output()
p.sayhi() #错误,不能通过对象名调用
类方法(@classmethod)
只能通过类名调用实现,具有cls参数
class person():
@classmethod
def sayhi(cls):
print("hello !")
person.sayhi()
静态方法( @staticmethod)
只能通过类名访问,不能访问属于对象的成员、只能访问属于类的成员
class person():
name = 'zhangsna'
@staticmethod
def getname():
return person.name
@staticmethod
def setname(name):
person.name = name
print(person.getname())
person.setname( 'lilin' )
print(person.getname())
构造函数(init)
构造函数__init__为属性设置初值,每次创建类实例时,构造函数都会自动调用。
def __init():
函数体
析构函数(del_)
析构函数__del__用来释放对象占有的资源,在python回收对象空间之前自动执行,自动完成内存清理工作。
class person():
def __init__(self,n):
self.name = n
print('data born...')
def sayhi(self):
print('hello,my name is ',self.name)
def __del__(self):
print('name is ',self.name,',data dead...')
p1 = person('lin')
p1.sayhi()
p2 = person('zhang')
p2.sayhi()
del p1
del p2
继承
继承性是通过派生类和基类实现的,基类又称为父类或超类,派生类又称为子类,子类继承父类
class SubClassName(ParentClass1[,ParentClass2,ParentClass3,...]):
class_suit
1.支持多重继承,只需在类名后面的小括号中列出多个基类名,用逗号隔开
2.基类的构造函数(init)不会自动调用,必须在派生类中显示调用
3.调用基类方法时,需要加上基类的类名作为前缀,带上self参数
class SchoolMember(object): #父类
def __init__(self,name,age):
self.name = name
self.age = age
print('initialized SchoolMember: ',self.name)
def tell(self):
print('Name: {0} Age: {1}'.format(self.name,self.age))
class Teacher(SchoolMember): #子类
def __init__(self,name,age,salary):
SchoolMember.__init__(self,name,age) #基类的构造函数(__init__)不会自动调用,必须在派生类中显示调用
self.salary = salary
print('initialized Teacher: ',self.salary)
def tell(self):
SchoolMember.tell(self) #调用基类方法时,需要加上基类的类名作为前缀,带上self参数
print('salary: ',self.salary)
class Student(SchoolMember): #子类
def __init__(self,name,age,marks):
SchoolMember.__init__(self,name,age)
self.marks = marks
print('initialized Student: ',self.marks)
def tell(self):
SchoolMember.tell(self)
print('marks: ',self.marks)
t = Teacher('zhangsan',40,30000)
s = Student('lisi',20,75)
member = [t,s]
for m in member:
m.tell()
多继承
如果继承的多个类每个类中都定了相同的函数时:
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
#经典类
class C1:
pass
class C2(C1):
pass
#新式类
class C1 (object):
pass
class C2(C1):
pass
多态性
python通过方法重载和运算符重载实现多态性
方法重载
在子类中使用与父类完全相同的方法名,从而重载父类方法
class A(object):
def show(self):
print('calling parent method...')
class B(A):
def show(self):
print('calling children method...')
p = A()
c = B()
c.show()
p.show()
运算符重载
python规定了每一个类都默认内置了所有可能的运算符方法,只要重写这个方法就可以实现针对该运算符的重载。
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2