对象的几个特征: 封装、继承、多态
1继承:
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属性了,此时有两种解决方案:
1.1调用未绑定的父类方法
1.2使用super函数
使用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()
2多重继承:
python允许多重继承,即可以同时继承多个父类的方法和属性.多重继承会使得代码看起来比较乱,因此如果不确定一定要使用多重继承的时候,尽量避免使用它,而且有时候会出现不可预测的bug。对于程序来说,不可预测的bug可能会是致命的。
语法:
class DerivedClassName(Base1, Base2, Base3):
....
3多态:
不同对象对同一方法反应不同的行动
从上图可以看出,python中的私有变量是伪私有,__name可以通过_Person__name来访问到,python的类是没有权限控制的,因此变量是可以被外部访问的。