对象的几个特征: 封装、继承、多态
class DerivedClassName(BaseClassName): 其中BaseClassName也称为基类、父类或超类
子类可以继承父类的各种属性和方法,但是如果子类如果有与父类同名的方法或属性,那么子类将会自动覆盖父类的方法和属性
class Fish: def __init__(self): self.x = r.randint(0,10) self.y = r.randint(0,10) def move(self): self.x -= 1 print("my location is:",self.x,self.y) class Goldfish(Fish): pass class Carp(Fish): pass class Salmon(Fish): pass class Shark(Fish): def __init__(self): self.hungry = True def eat(self): if self.hungry: print("eat something") self.hungry = False else: print("do not need eat") fish = Fish() fish.move() goldfish = Goldfish() goldfish.move() shark = Shark() shark.eat() shark.move() 上述代码在运行时,在shark.move()时会报错,如下图:
原因是Shark的__init__方法将Fish的初始化方法覆盖了,于是没有x属性了,此时有两种解决方案:
使用super函数能够自动帮我们找到父类的方法,还可以为我们传递参数,不需要我们做这些调用未绑定的父类方法。super的好处是不需要明确给出父类的名字,因为有时候一个类可能一路继承了很多父类,super()会一层层找出所有类里面对应的方法。当不需要给定父类的名字时,如果想改变继承关系,只需要改变类定义class DerivedClassName(BaseClassName) 中的BaseClassName就可以,而不用管类内的属性和方法,因为类内都是super(),而不是某个具体的父类。
经过改变后新的代码为:
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("my location is:",self.x,self.y) class Goldfish(Fish): pass class Carp(Fish): pass class Salmon(Fish): pass class Shark(Fish): def __init__(self): Fish.__init__(self) #方案一:调用父类的方法,这里是未绑定的父类方法,因为是用的子类的实例对象去调用的父类初始化方法 super().__init__() #方案二: 使用super()函数,能够自动找到父类的方法,并且会自动传递参数 self.hungry = True def eat(self): if self.hungry: print("eat something") self.hungry = False else: print("do not need eat") fish = Fish() fish.move() goldfish = Goldfish() goldfish.move() shark = Shark() shark.eat() shark.move()python允许多重继承,即可以同时继承多个父类的方法和属性.多重继承会使得代码看起来比较乱,因此如果不确定一定要使用多重继承的时候,尽量避免使用它,而且有时候会出现不可预测的bug。对于程序来说,不可预测的bug可能会是致命的。
语法:
class DerivedClassName(Base1, Base2, Base3):
....
不同对象对同一方法反应不同的行动
从上图可以看出,python中的私有变量是伪私有,__name可以通过_Person__name来访问到,python的类是没有权限控制的,因此变量是可以被外部访问的。
