面向对象编程是一种编程方式,最主要的特点是需要使用 "类"和 "对象" 来实现,类可以看作一个模板,模板里可以包含很多方法,方法可以实现一些功能;对象则是创建模板的实例,通过实例对象可以执行类中的方法。
类
1.认识类
通常我们把“鸟类”想象成所有鸟的集合,因此“鸟类”就是一个非常抽象的类;鸟普遍能飞需要食物,因此“能飞”和“需要食物”就是这个类的属性。再者我们不会说这是一只鸟类,而只会说这是一只鸟,于是“这只鸟”便成了“鸟类”的实例。
1 >>> class Bird: 2 def __init__(self): 3 self.hungry = True 4 def eat(self): 5 if self.hungry: 6 print "55555" 7 self.hungry = False 8 else: 9 print "no,thanks!" 10 11 >>> b = Bird() #b是类Bird的实例 12 >>> b.eat() 13 55555
如果说“鸟类”是一个类,那“百灵鸟”便是“鸟类”的一个子类;反言之,“鸟类”是“百灵鸟”的父类,这是一只百灵鸟,也可以说“这只百灵鸟”是“百灵鸟”的实例化。
1 >>> class Lark(Bird): 2 def __init__(self): 3 self.sound = ‘JOJO‘ 4 def sing(self): 5 print self.sound 6 7 >>> lark = Lark() 8 >>> lark.sing 9 <bound method Lark.sing of <__main__.Lark instance at 0x03AB98A0>> 10 >>> lark.sing() 11 JOJO
2.定义子类
通常一个类的定义取决于它所支持的方法,子类可以继承父类所有的方法;于是定义一个子类,便是一个定义更多方法(也可能是重载已经存在的方法)的过程。比如,企鹅Penguin(Bird的子类)不会fly,当创建Penguin类时,可能会想要重写父类的fly方法,对于Penguin的实例来说,这个fly方法要不什么也做不了,要不就会异常,因为企鹅不会飞。
1 >>> lark.eat() #子类对象调用父类eat()方法 2 3 Traceback (most recent call last): 4 File "<pyshell#61>", line 1, in <module> 5 lark.eat() 6 File "<pyshell#48>", line 5, in eat 7 if self.hungry: 8 AttributeError: Lark instance has no attribute ‘hungry‘
调用Bird类的eat方法异常,是因为Lark类的构造方法__init__被重写了,新的构造方法没有初始化父类hungry属性的代码,正确的应该是在self.sound = ‘JOJO‘代码前,加上Bird.__init__(self),python3.5也可以用super(Lark.self).__init__()代替。
1 >>> class Lark(Bird): 2 def __init__(self): 3 Bird.__init__(self) #或者super(Lark.self).__init__() 4 self.sound = ‘JOJO‘ 5 def sing(self): 6 print self.sound 7 8 >>> lark = Lark()9 >>> lark.eat() 55555
构造方法:代表着名为init的初始化方法,和其他普通方法不同在于,当一个对象被创建后,会立即调用构造方法,用来初始化新创建对象的状态,大多数子类不仅要用于自己的初始化代码,还要父类的初始化代码。
3. 私有方法
方法或特性若公有变为私有(从类外部无法访问),只需要在它的名字前面加上双下划线即可。
1 >>> class Secretive: 2 def __A(self): 3 print ‘no see‘ 4 def B(self): 5 print ‘hello,you can see me‘ 6 7 >>> s1 = Secretive() 8 >>> s1.A() 9 10 Traceback (most recent call last): 11 File "<pyshell#69>", line 1, in <module> 12 s1.A() 13 AttributeError: Secretive instance has no attribute ‘A‘ 14 >>> s1.B() 15 hello,you can see me
4.创建内建类型的子类
一般内建对象是基于类型(list,tuple,string,dic和number)的,自定义的对象则是基于类的。可以创建类但是不能创建类型。但是最新的python,基本类型和类的界限开始模糊了。
1 >>> class CountList(List): #定义一个带访问计数的列表 2 def __init__(self,*args): 3 super(CountList,self).__init__(*args) #python2.7不可以用super直接调用自身,获得父类方法,只能用List__init__(self):代替 4 self.counter = 0 5 def __getitem__(self,index): 6 self.count += 1 7 return super(CountList,self).__getitem__(index) 8 9 10 >>> c1 = CounterList(range(5)) 11 [1,2,3,4,5] 12 >>> c1.counter 13 0 14 >>>c1[2] +c1[3] 15 7 16 >>>c1.counter 17 2
对象
在Python中一切皆对象,对象(object)基本上可以看作数据(属性)以及操作这些数据的方法组成的集合。对象的特点:
a.多态:意味着可以对不同类的对象使用相同的操作,很多函数和运算符都是多态的
1 >>> def add(x,y): 2 return x + y 3 4 >>> add(1,2) 5 3 6 >>> add(‘abc‘,‘ef‘) 7 ‘abcef‘
b.封装:把类所需要的数据(类的属性)和对数据的操作(类的方法)全部都写进类的过程,简化编程,对外部隐藏内部工作细节。
1 >>> class Person: 2 def __init__(self): 3 self.name = ‘ann‘ 4 >>> p1 = Person() 5 >>> p1.name 6 ‘ann‘ 7 >>> p1.name = ‘Ryana‘ 8 >>> p1.name 9 ‘Ryana‘ 10 11 >>> p2 = Person() 12 >>> p2.name 13 ‘ann‘ 14 #创建不同的对象p1和p2,名字不同说明对象都有自己的状态,对象的状态由它的属性(eg:name)来描述,对象的方法可以改变它的属性
c.继承:继承是两个类或者多个类之间的父子关系,实现了代码的重用,通过父类为基础建立专门的类对象,以达到调用更多方法的目的。检查继承,issubclass(A,B):A类是否是B类的子类,isinstance(a,A):对象a是否是类A的实例
1 >>> issubclass(Lark,Bird) 2 True 3 >>> issubclass(Bird,Lark) 4 False 5 6 >>> isinstance(lark,Lark) 7 True 8 >>> isinstance(lark,Bird) 9 True