# 面向对象的三大特性
# 继承
# 多态
# 封装
# 继承
# 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又被称为基类或超类,新建的类称为派生类或子类
# 一个类可以被多个类继承
# python中特性的是,一个类可以继承多个父类(多继承)
# object是类祖宗
# 在python3中所有的类,没有继承父类的话,默认会继承object类. python3的类为新式类
# 继承与抽象(先抽象再继承)
# 抽象即抽取类似或者说比较像的部分
# 抽象分成两个层次:
# 1.将奥巴马和梅西这俩对象比较像的部分抽取成类
# 2.将人、猪、狗这三个类比较像的部分抽取成父类
# 抽象最主要的作用是划分类别(可以隔离关注点、降低复杂度)
# 继承是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构
# 抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类
# 父类中没有的属性,在子类中出现,叫做派生属性
# 父类中没有的方法,在子类中出现,叫做派生方法
# 子类的对象调用,子类中有则会使用子类的,子类中没有如果基类中则会使用基类的,基类中没有则会报错,子类和基类中都有会使用子类的
class A: # 父类/基类/超类
pass
class B: # 父类/基类/超类
pass
class A_son(A): # 子类/派生类, 继承父类A
pass
class AB_son(A, B): # 子类/派生类, 同时继承自父类A、父类B
pass
# 单继承
print(A_son.__bases__) # 查看自己继承了哪些基类 (<class '__main__.A'>,)
print(A.__bases__) # (<class 'object'>,) object是类祖宗
class Animal:
def __init__(self, name, aggr, hp):
self.name = name
self.aggr = aggr
self.hp = hp
# 狗, 继承了动物,
class Dog(Animal):
def bite(self, persion):
persion.hp += self.aggr
# 人,继承了动物
class Persion(Animal):
def attack(self, dog):
dog.hp -= self.aggr
def get_weapon(self, weapon): # 获得装备
if self.money >= weapon.price:
self.money -= weapon.price
# 对象没有这个属性值则会创建一个weapon属性值
self.weapon = weapon # 一个对象的属性值是另外一个类的对象 组合
self.aggr += weapon.aggr
else:
print('金币不足,请获取足够金币')
jin = Dog('金老板', 100, 500) # 优先调用dog的__init__方法,没有则会使用父类的__init__
print(jin.name)
# 继承的练习
# 狗类 吃、喝、看门
# 鸟类 吃、喝、下蛋
class Animal:
def __init__(self):
print('执行Animal.__init__')
self.func()
def eat(self):
print('%s eating' % self.name)
def drink(self):
print('%s drinking' % self.name)
def func(self):
print(Animal.func)
class Dog(Animal):
def guard(self):
print('guarding')
def func(self):
print('Dog.func')
dog = Dog() # 执行Animal.__init__ Dog.func
# 继承例子
# 基类
class Animal:
def __init__(self, name, aggr, hp):
self.name = name
self.aggr = aggr
self.hp = hp
def eat(self):
print('%s 吃药回血' % self.name)
self.hp += 100
# 狗继承了动物,
class Dog(Animal):
def __init__(self, name, aggr, hp, kind):
Animal.__init__(self, name, aggr, hp)
self.kind = kind # 派生属性,子类增加的属性
def eat(self):
Animal.eat(self) # 如果既想实现父类eat的功能,又想实现子类新的eat功能,则在子类中再调用父类的方法,需要传self参数
#super().eat()
self.teeth = 2
def bite(self, persion):
persion.hp -= self.aggr
# 人
class Persion(Animal):
def __init__(self, name, aggr, hp, sex):
#Animal.__init__(self, name, aggr, hp)
super().__init__(name, aggr, hp) #super类中只在新式类中有, python3中所有的类都是新式类,super可以找到父类,从而可以调用父类的方法,默认不用传参数
#super(Persion, self).__init__(name, aggr, hp) # 相当于上面那行,这是完整的,实际传参的形式
self.sex = sex # 派生属性,子类增加的属性
self.money = 0 # 派生属性,子类增加的属性
def eat(self):
print('%s eating' % self.name)
def attack(self, dog): # 派生方法,基类没有的方法
dog.hp -= self.aggr
def get_weapon(self, weapon): # 获得装备 # 派生方法,基类没有的方法
if self.money >= weapon.price:
self.money -= weapon.price
# 对象没有这个属性值则会创建一个weapon属性值
self.weapon = weapon # 一个对象的属性值是另外一个类的对象 组合
self.aggr += weapon.aggr
else:
print('金币不足,请获取足够金币')
jin = Dog('金老板', 100, 500, '吉娃娃')
print(jin.name)
jin.eat() # Dog类中有eat,则调用Dog类中的eat,当然是自己对象命名空间中调用
print(jin.hp)
print(jin.teeth)
alex = Persion('alex', 100, 500, 'nan')
alex.eat() # 调用的是基类的方法
super(Persion, alex).eat() # 吃药回血 调用的是Persion父类的eat super(类名、self(类对象))
print(alex.hp)
jin.bite(alex)
print(alex.hp)