基础知识回顾——类和对象

面向对象编程是一种编程方式,最主要的特点是需要使用 "类"和 "对象" 来实现,类可以看作一个模板,模板里可以包含很多方法,方法可以实现一些功能;对象则是创建模板的实例,通过实例对象可以执行类中的方法。

 

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

 

posted on 2017-01-14 13:15  Ryana  阅读(271)  评论(0编辑  收藏  举报