对象=属性(特征)+方法(行为)
类:在python中,把具有相同属性和方法的对象归为一个类(class)
self:
>>> class Ball:
def setName(self,name):
self.name = name
def play(self):
print("我叫%s,我会打篮球~" %self.name)
>>> a = Ball()
>>> a.setName("库里")
>>> b = Ball()
>>> b.setName("欧文")
>>> c = Ball()
>>> c.setName("哈登")
>>> a.play()
我叫库里,我会打篮球~
>>> b.play()
我叫欧文,我会打篮球~
>>> c.play()
我叫哈登,我会打篮球~
init()构造方法,只要实例化一个对象,这个方法就会在对象被创建时自动调用。
>>> class Ball:
def __init__(self,name):
self.name = name
def play(self):
print("我叫%s,我会打篮球~" %self.name)
>>> d = Ball("科比")
>>> d.play()
我叫科比,我会打篮球~
公有和私有
>>> class Superstar:
name = "Kobe"
>>> a = Superstar()
>>> a.name
'Kobe'
>>>
>>> class Superstar:
__name = "Kobe"
>>> a = Superstar()
>>> a.name
Traceback (most recent call last):
File "" , line 1, in
a.name
AttributeError: 'Superstar' object has no attribute 'name'
变量名“隐藏”
>>> class Superstar:
def __init__(self,name):
self.__name = name
def getName(self):
return self.__name
>>> p = Superstar("Kobe")
>>> p.__name
Traceback (most recent call last):
File "" , line 1, in
p.__name
AttributeError: 'Superstar' object has no attribute '__name'
>>> p.getName()
'Kobe'
这只是伪私有,其实所有的类都是可以被外部调用的。
继承
>>> class Parent:
def hello(self):
print("我是你的爸爸")
>>> class Child(Parent):
pass
>>> a = Parent()
>>> a.hello()
我是你的爸爸
>>> c = Child()
>>> c.hello()
我是你的爸爸
>>>
需要注意,如果子类中定义与父类同名的方法或者属性,则会自动把父类覆盖掉。
>>> class Child(Parent):
def hello(self):
print("我是你儿子吧")
>>> c = Child()
>>> c.hello()
我是你儿子吧
继承的另一个例子
import random as r
class Ball:
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)
class Curry(Ball):
pass
class Irving(Ball):
pass
class Harden(Ball):
pass
class Kobe(Ball):
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print("吃饱了才有力气打球")
self.hungry = False
else:
print("刚吃完,得打球了")
运行得到
>>> curry = Curry()
>>> curry.move()
我的位置是: 1 1
>>> curry.move()
我的位置是: 0 1
>>> curry.move()
我的位置是: -1 1
>>> curry.move()
我的位置是: -2 1
>>> curry.move()
我的位置是: -3 1
>>> curry.move()
我的位置是: -4 1
>>> curry.move()
我的位置是: -5 1
下面试试科比:
>>> kobe = Kobe()
>>> kobe.eat()
吃饱了才有力气打球
>>> kobe.eat()
刚吃完,得打球了
>>> kobe.move()
Traceback (most recent call last):
File "" , line 1, in
kobe.move()
File "C:/Users/Administrator/AppData/Local/Programs/Python/Python36/p11_2.py", line 9, in move
self.x -= 1
AttributeError: 'Kobe' object has no attribute 'x'
kobe没有x属性,因为在Kobe类中,重写了魔法方法init_(),但是没有初始化科比的x坐标和y坐标,因此调用move()会出错。解决方法:在kobe类中重写__init()方法的时候先调用基类Ball()的init方法。
class Kobe(Ball):
def __init__(self):
Ball.__init__(self)
self.hungry = True
kobe也可以成功运行:
>>> kobe = Kobe()
>>> kobe.move()
我的位置是: 1 9
>>> kobe.move()
我的位置是: 0 9
>>> kobe.move()
我的位置是: -1 9
这里需要注意的是,这个self并不是父类Ball的实例对象,而是子类Kobe的实例对象,所以说未绑定指并不需要绑定父类的实例对象,使用子类的实例对象代替即可。
不理解也没关系,因为,super函数可以代替它
super
class Kobe(Ball):
def __init__(self):
super().__init__()
self.hungry = True
运行之后得到:
>>> kobe = Kobe()
>>> kobe.move()
我的位置是: 0 9
>>> kobe.move()
我的位置是: -1 9
>>> kobe.move()
我的位置是: -2 9
super函数的神奇之处在于,你不需要给出任何基类的具体名字,它会自动找到所有基类以及对应的方法。
多重继承
>>> class Base1:
def f1(self):
print("f1")
>>> class Base2:
def f2(self):
print("f2")
>>> class C(Base1,Base2):
pass
>>> c = C()
>>> c.f1()
f1
>>> c.f2()
f2
组合
把不同的类直接放进去实例化,就叫组合:
class Curry:
def __init__(self,x):
self.num = x
class Irving:
def __init__(self,x):
self.num = x
class All_star:
def __init__(self,x,y):
self.curry = Curry(x)
self.irving = Irving(y)
def print_num(self):
print("库里%d,欧文%d"%(self.curry.num,self.irving.num))
运行 组合.py得到:
>>> a = All_star(30,2)
>>> a.print_num()
库里30,欧文2
类、类对象和实例对象
>>> class C:
count = 0
>>> a = C()
>>> b = C()
>>> c = C()
>>> print(a.count,b.count,c.count)
0 0 0
>>> c.count +=10
>>> print(a.count,b.count,c.count)
0 0 10
>>> C.count += 100
>>> print(a.count,b.count,c.count)
100 100 10