本文实例讲述了python面向对象之类和对象。分享给大家供大家参考,具体如下:
类和对象(1)
对象是什么?
对象=属性(静态)+方法(动态);
属性一般是一个个变量;方法是一个个函数;
#类的属性 就是 类变量
#实例变量:定义在方法中的变量,只作用于当前实例的类。
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class turtle: #python 中类名约定以大写字母开头
'''关于类的简单例子。。。'''
#属性 == 类变量
color = "green"
weight = "10kg"
legs = 4
shell = true
mouth = 'big'
#方法
def climb( self ):
self .name = "test" #实例变量:定义在方法中的变量,只作用于当前实例的类。
print ( "我在很努力爬。" )
def run( self ):
print ( '我在很努力跑。' )
def bite( self ):
print ( '我要要要要要' )
def sleep( self ):
print ( '我要睡觉啦。' )
#创建一个实例对象也就是类的实例化!
tt = turtle() #类的实例化,也就是创建一个对象,类名约定大写字母开头
tt.bite() #创建好类后就能调用类里面的方法叻;
tt.sleep()
|
面向对象的特征:
oo = object oriented(面向对象)
1.封装(信息隐蔽技术)
python的列表list其实就是一个对象,它提供了很多方法:sort()、append()
封装后就可以直接调用里面的方法了!!!
2.继承
子类自动共享父类之间数据和方法的机制。
1
2
3
4
|
class mylist( list ): #创建一个类继承list的所有方法和属性
pass #相当于一个占位符
list1 = mylist() #类实例化
list1.append( 1 ) #继承后调用list的方法append()
|
3.多态
不同对象对同一方法响应不同行动。就是名字一样方法不一样:
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> class a:
def fun( self ):
print ( 'aaaa' )
>>> class b ():
def fun( self ):
print ( 'bbb' )
>>> a = a()
>>>b = b()
>>>a.fun()
aaaa
>>>b.fun()
bbb
|
类和对象(2)
self是什么?
如果把类当做图纸,那么由类实例化后的对象就是可以住人的房子。self就相当于房子的门牌号,由self就可以找到对象。
一个类可以生成无数个对象,对象之间都很相似,因为都是来源与类的方法属性。当对象方法被调用时,对象就会将自己作为第一个参数传给self,python就是根据self知道哪一个对象在调用方法;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
>>> class ball():
def setname( self ,name):
self .name = name
def kick ( self ):
print ( "我叫%r,谁踢我" % self .name)
>>>a = ball() 实例化生成a对象
>>>a.setname( 'a' ) 调用方法设名为a
>>>b = ball()
>>>b.setname( 'b' )
>>>c = ball()
>>>c.setname()
>>>a.kick () 通过 self 知道是哪个对象调用kick方法
我叫 'a' ,谁踢我
>>>b.kick()
我叫 'b' ,谁踢我
|
python的魔法方法:
__init__(self)
这个是构造方法。
实例化一个对象时,这个方法就会在对象创建时(实例化类就是创建对象)自动调用。实例化时就会调用__init__(self)
这个方法。
实例化对象是可以传入参数的,这些参数被传入init方法中,可通过重写方法来自定义对象初始化操作。
1
2
3
4
5
6
7
8
|
>>> class ball:
def __init__( self ,name):
self .name = name
def kick( self ):
print ( '我叫%r,谁踢我' % self .name)
>>> b = ball( 'b' ) #创建对象,这时__init__(self):就被调用了,可以传入b
>>>b.kick()
我叫 'b' ,谁踢我
|
公有和私有:
公有和私有数据类型。python中对象的属性和方法都是公开的都是公有的通过.操作符访问。
python中定义私有变量只需在变量名或函数名前增加两个下划线‘__',那么这个函数、变量变为私的了。
1
2
|
>>> class p():
__name = "liyue" #私有变量,外部不能通过.操作符直接访问了
|
类和对象(3):继承
语法:
1
2
|
class a(b):
………….
|
b我们叫父类、基类或超类;
a我们叫子类,子类继承父类的属性和方法;
例子:
1
2
3
4
5
6
7
8
9
10
11
|
>>> class parent():
defhello( self ):
print ( "helloliyue!" )
>>> class child(parent):
pass
>>> p = parent()
>>> p.hello()
hello liyue!
>>> c = child()
>>> c.hello()
hello liyue!
|
注意:如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。
例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> class parent():
defhello( self ):
print ( "helloliyue!" )
>>> class child(parent):
defhello( self ):
print ( "hahah!" )
>>> p = parent()
>>>p.hello ()
hello liyue!
>>> c = child()
>>>c.hello () #子类和父类方法相同,(子类重写父类方法)会覆盖父类方法,但是父类自己的方法不变
hahah!
|
super()
函数:解决了子类就算重写父类方法或属性仍然可以继续使用父类的方法和属性。
具体实例及说明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
import random as r
#利用继承演示鱼游动方向位置。
class fish(): #父类
def __init__( self ):
self .x = r.randint( 0 , 10 )
self .y = r.randint( 0 , 10 )
def move( self ):
self .x - = 1 #一直向西移动
print ( "我的位置是:" , self .x, self .y)
classgoldfish(fish): #子类
pass
classcarp(fish): #子类
pass
classsalmon(fish): #子类
pass
classshark(fish):
def __init__( self ): #这里重写了__init__方法,就会覆盖掉父类的方法了,用到super函数后就可以继续使用父类的方法。
#super函数不用给定任何基类的名字(如下),它会一层层找出代码所有父类里面对应的方法,要改变该类的继承关系时只需修改这个类的父类就行就是括号里面的fish。
super ().__init__() #super().重写的属性或方法
self .hungry = true
def eat( self ):
if self .hungry:
print ( "我要吃了。。。" )
self .hungry = false
else :
print ( '好饱了。。。' )
>>> f = fish()
>>>f.move()
我的位置是: - 1 3
>>>f.move()
我的位置是: - 2 3
>>>g = goldfish()
>>>g.move()
我的位置是: 4 4
>>>s = salmon()
>>>s.move()
我的位置是: 8 1
>>>s.move()
我的位置是: 7 1
>>> s = shark()
>>>s.eat()
我要吃了。。。
>>>s.eat()
好饱了。。。
>>>s.move()
我的位置是: 5 10 #这就是子类就可以使用父类的move()方法
>>>s.move()
我的位置是: 4 10
|
类和对象(4)
1.组合:一般把几个没有什么关系的类放在一起使用时通过组合类的方法。
例子:要求定义一个类,叫水池,水池里面有乌龟和鱼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class turtle(): #定义乌龟类
def __init__( self ,x):
self .num = x
classfish(): #定义鱼类
def __init__( self ,y):
self .num = y
classpool(): #定义水池类
def __init__( self ,x,y):
self .turtle = turtle(x) #直接把需要的类在这里实例化就行了,组合实现
self .fish = fish(y)
def print_num( self ):
print ( "水池中总共有乌龟%d只,小鱼%r条。" % ( self .turtle.num, self .fish.num)
>>> p = pool( 1 , 10 )
>>>p.print_num ()
水池中总共有乌龟 1 只,小鱼 10 条
|
这就是组合,组合就是把类的实例化放到一个新类里面,他就把旧类组合进去了。
组合一般就是说把几个不是有继承关系的、没有直线关系的几个类放在一起,如果要实现纵向关系的几个类,就是继承。
2.类、类对象、实例对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
>>> class c(): #类,当类写完后就变成了类对象
def x( self ):
print ( "xaaa" )
>>> c = c() #c是实例对象,c()是类对象
>>> c.x()
xaaa
>>> c.x = 1 #实例对象初始化一个变量
>>> c.x
1
>>> c.x() #就不能继续调用原来的方法了,同名会覆盖掉类的方法
traceback (most recent call last):
file "<pyshell#18>" , line 1 , in <module>
c.x()
typeerror: 'int' object is not callable
|
所以:不要试图在一个类里面定义所有的属性和方法,应该利用继承和组合机制;
用不同的词性命名,如属性名用名词,方法名用动词。
3.什么是绑定?
python严格要求方法需要有实例才能被调用,这种限制其实就是绑定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
>>> class cc: #类
def setxy( self ,x,y):
self .x = x
self .y = y
def printxy( self ):
print ( self .x, self .y)
>>> dd = cc() #实例对象,类对象
>>>dd.__dict__ #查看实例对象所拥有的属性
{}
>>>cc.__dict__ #查看类对象所拥有的属性
mappingproxy({ 'setxy' :<function cc.setxy at 0x00000000031f9b70 >, 'printxy' : <functioncc.printxy at 0x00000000031f9bf8 >, '__module__' : '__main__' , '__weakref__' :<attribute '__weakref__' of 'cc' objects>, '__dict__' : <attribute '__dict__' of 'cc' objects>, '__doc__' : none})
>>>dd.setxy ( 4 , 5 ) #实例对象中传入x,y
>>>dd.__dict__ #实例对象就有属性了,这两个属性紧属于实例对象的,类对象中是没有的
{ 'y' : 5 , 'x' : 4 } #类对象中是没有实例对象传入的,这归功与绑定这个功能,self
|
为什么实例对象调用方法后类对象中没有实例对象的属性?
实例对象调用方法时,dd.setxy(dd,4,5) 实际上是这样的,也就是(self.x = x;self.y = y)dd.x=4,dd.y=5,那么4,5存放在实例对象的空间,故这两个属性只属于实例对象的。(实例对象调用类方法时,先把自己传给self,self.x也就是dd.x.)
类对象与实例对象差别:
把类对象cc删除后,del cc,再实例化就会报错,但是已经实例化对象dd仍然可以调用类对象中的方法:
1
2
3
4
5
6
7
8
9
10
11
|
>>> delcc
>>>dd.setxy ( 3 , 4 )
>>>dd.__dict__
{ 'y' : 4 , 'x' : 3 }
>>> dd = cc()
traceback (most recent call last):
file "<pyshell#45>" , line 1 , in <module>
dd = cc()
nameerror: name 'cc' is not defined
>>>dd.printxy ()
3 4
|
为什么已经实例化对象dd仍然可以调用类对象中的方法?
类中定义的属性是静态变量,方法也一样,就算类对象被删除了,属性和方法一样存放在内存中,故实例对象仍然可以从内存中调用类的方法和属性,除非程序退出。所以创建一个类后最好先实例化再使用类对象中的方法,不要直接利用类对象调用方法。
self.x self相当于实例对象的名字,.x就是实例的空间了
希望本文所述对大家python程序设计有所帮助。
原文链接:https://blog.csdn.net/JOJOY_tester/article/details/53246557