面向对象--继承
面向对象--继承
1.面向对象三大特性:封装、继承、多态
2.继承是类中提供的一种新语法,继承表达了一种什么是什么的关系
3.在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
class Animal: #基类、父类、超类
pass
class Dog(Animal): #子类
pass
class Cat(Animal): #子类
pass
4.继承分为:单继承、多继承
class A:
def hahaha(self):
print('A')
class C:
def hahaha(self):
print('C')
class B(C,A):
def hahaha(self):
super(B,self).hahaha()
super(B,self).hahaha()
print('B')
super().hahaha()
b=B()
b.hahaha()
super(B,b).hahaha()
5.__base__只查看从左到右继承的第一个父类,__bases__则是查看所有继承的父类
6.如果没有指定基类,python的类会默认继承object类,object是所有python类的基类
7.抽象与继承:先抽象再继承
(1)抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类
(2)是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构
8.在继承中,子类可以继承父类所有的属性与方法,但是当父类和子类中有同名的方法时,一定调用子类的方法,如果想调用父类该方法的功能,需用super方法
class Animal:
def __init__(self,name,food):
self.name=name
self.food=food
def eat(self):
print('%s eating %s'%(self.name,self.food))
def drink(self):
print('drinking')
def sleep(self):
print('sleeping')
# # 狗
class Dog(Animal):
def __init__(self,name):
super().__init__(name,'狗粮') #新式类执行父类的方式
self.name=name
self.food='狗粮'
def say(self):
print('汪汪汪')
wang=Dog('aa')
wang.eat()
wang.say()
9.对象可以调用自己本类和父类的所有属性和方法,谁(对象)调用方法,方法中的self就指向谁
class Animal:
def __init__(self,name,food):
self.name = name
self.food = food
self.family = '刘老师家'
def eat(self):
print('%s 吃 %s'%(self.name,self.food))
class Dog(Animal):
def __init__(self,name):
super().__init__(name, '狗粮')
self.family = '景弘家'
def swim(self):
print('%s is swimming'%self.name)
class Bird(Animal):
def fly(self):
print('%s is flying'%(self.name))
teddy = Dog('熊二') #init
teddy.eat()
teddy.swim()
print(teddy.family)
10.派生属性:父类没有的属性,是子类自己加的属性;
派生方法:父类没有的方法,是子类自己加的方法。
class Animal: #父类 超类 基类
def __init__(self,name,blood,aggr):
self.name = name
self.blood = blood
self.aggr = aggr
class Person(Animal): #继承的语法 Person是子类
def __init__(self, name, blood, aggr,RMB):
super(Person, self).__init__(name,blood,aggr)
self.qian=RMB
def attack(self,dog):
dog.blood -= self.aggr
class Dog(Animal): #Dog是子类
def __init__(self, name, blood, aggr, pinzhong):
super().__init__(name,blood,aggr)
self.breed= pinzhong #派生属性
def bite(self,person): #派生方法
person.blood -= self.aggr
11.抽象类和接口类:是一种编程思想,为子类做好规范
(1)归一化设计:几个类都实现相同的方法
from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta): #接口类
@abstractmethod
def payment(self,money):
raise NotImplemented
class Applepay(Payment):
def payment(self,money):
print('apple 支付了 %d元'%money)
class Alipay(Payment):
def payment(self,money):
print('支付宝 支付了 %d元'%money)
def payment(pay_obj,money):
pay_obj.payment(money)
class Wechatpay(Payment):
def payment(self,money):
print('微信 支付了 %d元'%money)
apple=Applepay()
payment(apple,100)
ali=Alipay()
wechat=Wechatpay()
payment(ali,700)
payment(wechat,200)
(2)抽象类:最好单继承,可以实现简单的功能
from abc import abstractmethod,ABC
class Foo(metaclass=ABCMeta): #抽象类
@abstractmethod
def read(self):
f=open('file')
f.close()
def write(self):
f=open('file')
f.close()
class File(Foo):
def read(self):
super().read()
def write(self):
super().write()
class Disk(Foo):
def read(self):
super().read()
def write(self):
super().write()
(3)接口类:可以多继承,最好不实现具体功能
from abc import abstractmethod,ABCMeta
class Fly_Animal(metaclass=ABCMeta):
@abstractmethod
def fly(self):
pass
class Swim_Animal(metaclass=ABCMeta):
@abstractmethod
def swim(self):
pass
class Walk_Animal(metaclass=ABCMeta):
@abstractmethod
def walk(self):
pass
class Tiger(Swim_Animal,Walk_Animal):
def walk(self):
print('tiger is walking')
class Frog(Swim_Animal,Walk_Animal):
def walk(self):
pass
def swim(self):
pass
class Swan(Fly_Animal,Swim_Animal,Walk_Animal):
def fly(self):
pass
def swim(self):
pass
def walk(self):
pass
(4)实现接口类和抽象类的语法
from abc import abstractmethod,ABCMeta
class 父类(metaclass=ABCMeta)
@abstractmethod
12.钻石继承问题:
(1)python的新式类和经典类在继承顺序上的不同
(2)经典类:深度优先
(3)新式类:广度优先,查看继承顺序:子类名.mro()
class D:
def test(self):
print('D')
class B(D):
def test(self):
print('B')
class C(D):
def test(self):
print('C')
class A(B,C):
def test(self):
print('A')
a=A()
a.test()
(1)在经典类中调用方法的顺序为:先调A自己的方法,调不到自己的方法
调B的方法,调不到B的方法调D的方法,调不到D的方法调C的方法
(2)在新式类中调用方法的顺序为:先找A自己的方法,调不到自己的方法
调B的方法,调不到B的方法调C 的方法,调不到C的方法调D的方法
class F:
def test(self):
print('F')
class E(F):
def test(self):
print('E')
class D(F):
def test(self):
print('D')
class B(D):
def test(self):
print('B')
class C(E):
def test(self):
print('C')
class A(B,C):
def test(self):
print('A')
a=A()
a.test()
经典类调用的顺序:A→B→D→F→E→C
新式类调用的顺序:A→B→D→C→D→F
13.编程原则:
(1)开放封闭原则:对扩展是开放的,对修改是封闭的
(2)依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节,细节应该依赖抽象,
要针对接口编程,而不是针对实现编程
(3)接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些不需要的接口


浙公网安备 33010602011771号