面向对象-继承
什么是继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
继承是类中提供的一种新语法
面向对象三大特性:封装 继承 多态
继承:什么是什么的关系
他大舅打二舅都是他舅
高桌子低板凳都是木头
继承语法,单继承和多继承
class ParentClass1: #定义父类
pass
class ParentClass2: #定义父类
pass
class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
pass
class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
pass
查看继承__bases__
类名.__bases__
>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
继承与抽象(先抽象,再继承)
抽象即抽取类似或者说比较像的部分。
抽象分成两个层次:
1.将奥巴马和梅西这俩对象比较像的部分抽取成类;
2.将人,猪,狗这三个类比较像的部分抽取成父类。
抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。
抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类
继承与重用性
#狗 class Dog: def eat(self): print('eating') def drink(self): print('drinking') def sleep(self): print('sleeping') def say(self): print('汪汪汪') #猫 class Cat: def eat(self): print('eating') def drink(self): print('drinking') def sleep(self): print('sleeping') def say(self): print('喵喵喵') #狗类和猫类都有 eat,drink,sleep 的方法,所有写一个父类,让子类继承父类的这些方法 class Animal: #父类、超类 def eat(self): pass def drink(self): pass def sleep(self): pass class Dog(Animal): #子类、派生类 子类继承父类的方法和属性 pass class Cat(Animal): #子类、派生类 pass dog = Dog() cat = Cat() dog.eat() dog.drink() dog.say() #汪汪汪 cat.eat() cat.drink() cat.say() #喵喵喵 print(Dog.__bases__)
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时
我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用
class Animal:
'''
人和狗都是动物,所以创造一个Animal基类
'''
def __init__(self, name, aggressivity, life_value):
self.name = name # 人和狗都有自己的昵称;
self.aggressivity = aggressivity # 人和狗都有自己的攻击力;
self.life_value = life_value # 人和狗都有自己的生命值;
def eat(self):
print('%s is eating'%self.name)
class Dog(Animal):
pass
class Person(Animal):
pass
egg = Person('egon',10,1000)
ha2 = Dog('二愣子',50,1000)
egg.eat()
ha2.eat()
派生
子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。
在继承中
子类可以继承父类的所有属性和方法
但是 当父类和子类中有同名方法的时候 一定调用子类的
如果想使用父类该方法的功能 需要借助super方法
super
子类中执行父类的方法super()
class A: def hahaha(self): print('A') class B(A): def hahaha(self): super().hahaha() #调用父类中的hahaha()方法 #super(B,self).hahaha() == A.hahaha(self) print('B') a = A() b = B() b.hahaha() #A B super(B,b).hahaha() #A 相当于调用父类中的hahaha()方法
实例一
class Animal: def __init__(self,name,food): self.name = name self.food = food def eat(self): print('%s吃%s'%(self.name,self.food)) def drink(self): print('%s喝水'%self.name) class Dog(Animal): def __init__(self,name): #子类对象初始化 实例化时只接受一个参数 super().__init__(name,'狗粮') #调用父类的__init__方法,需要传入两个参数 狗类的food就是狗粮 def swim(self): print('在游泳') class Bird(Animal): def __init__(self,name): super().__init__(name,'虫子') def fiy(self): print('%s在飞'%self.name) gou = Dog('旺财') gou.eat() gou.drink() niao = Bird('布谷鸟') niao.fiy() niao.eat() niao.drink()
实例二
class Animal: #定义父类 def __init__(self,name,blood,aggr): self.name =name self.blood = blood self.aggr = aggr class Person(Animal): #继承父类Animal def __init__(self,name,blood,aggr,money): #实例化一个人类时,要传入4个参数 super().__init__(name,blood,aggr) #共有的属性调用父类的__init__方法,传入父类__init__要传的参数 self.money = money #子类独有的属性 def attack(self,dog): dog.blood -= self.aggr class Dog(Animal): #继承父类Animal def bite(self,person): person.blood -= self.aggr alex = Person('alex',2000,100,100000) print(alex.money) #100000
面试题
class A:
def hahaha(self):
print('A')
class B(A):
def hahaha(self):
# super(B,self).hahaha()
super().hahaha()
print('B')
b = B()
b.hahaha() #A B
# super(B,b).hahaha() #A
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师
>>> class Teacher:
... def __init__(self,name,gender):
... self.name=name
... self.gender=gender
... def teach(self):
... print('teaching')
...
>>>
>>> class Professor(Teacher):
... pass
...
>>> p1=Professor('egon','male')
>>> p1.teach()
teaching
既然选择了远方,便是风雨兼程...