python查漏补缺--抽象类和接口以及Overrides、函数重载

目标:

掌握python中的抽象类和抽象接口。
封装和继承在java中用得挺多的,python中貌似用得真不多,但是为了应付考试,也是得了解。


学习内容:

抽象类,就是总结一些基本方法,每个子类必须自己实现这些方法。如果是接口,应该强制子类实现。不实现就报错。
python抽象类和接口的区别:接口中的方法全部需要用抽象方法,强制继承的对象实现。抽象类可以有部分方法已经实现
python 原生不支持接口类,需要导入abc包。python3.4以后自带此包,不用在pip install。

1、 定义一个抽象类。

from abc import abstractclassmethod,ABCMeta

class Car(metaclass=ABCMeta):
    @abstractclassmethod
    def price(self,money):
        pass
    @abstractclassmethod
    def carryPassengers(self):
        pass

class BaomaCar(Car):
    def price(self,money =300000):
        print('bao ma car is ' + money)
        
baomaCar = BaomaCar()
baomaCar.price()        

运行会报错:说必须实现抽象类中的方法carryPassengers

TypeError: Can't instantiate abstract class BaomaCar with abstract methods carryPassengers

然后修改代码:

from abc import abstractclassmethod,ABCMeta

class Car(metaclass=ABCMeta):
    @abstractclassmethod
    def price(self,money):
        pass
    @abstractclassmethod
    def carryPassengers(self):
        pass

class BaomaCar(Car):
    def price(self,money=30000):
        print('bao ma car is ' , money)
    def carryPassengers(self):
        print('bao ma car carry 5 passengers' )
        
baomaCar = BaomaCar()
baomaCar.price(350000)
baomaCar.carryPassengers()

可以正常运行。

bao ma car is  350000
bao ma car carry 5 passengers

2、 子类可以实现不一样的方法吗?
接着实现一个bus的Car对象。

class Bus(Car):
    def price(self):
        print('Bus car is ' , 500000)
    def carryPassengers(self):
        print('Bus car carry 20 passengers' )
bus = Bus()
bus.price()
bus.carryPassengers()

发现可以正常运行,说明abs中 @abstractclassmethod 只限制函数名,只要改函数名实现了就可以了。
3、 如果要强制子类实现一样参数的函数呢?
这就要导入overrides包,java中很常见。

from overrides import overrides
class Bus(Car):
    @overrides
    def price(self):
        print('Bus car is ' , 500000)
    def carryPassengers(self):
        print('Bus car carry 20 passengers' )
bus = Bus()
bus.price()
bus.carryPassengers()

运行报错:

TypeError: Bus.price: `money` is not present.

overrides要求子类的方法参数必须和父类一致,而且参数名都要一样(子类可以定义新的,但是父类的必须要有,因为python用参数名来确定给哪个参数传值)。当然可以赋初始值。

from overrides import overrides
class Bus(Car):
    @overrides
    def price(self,money=600000):
        print('Bus car is ' , money)
    def carryPassengers(self):
        print('Bus car carry 20 passengers' )
bus = Bus()
bus.price()
bus.carryPassengers()

运行结果:

Bus car is  600000
Bus car carry 20 passengers

4、 发现python对用了java格式的重载有点不支持。
代码如下:

from abc import abstractclassmethod,ABCMeta
class Car(metaclass=ABCMeta):
    @abstractclassmethod
    def price(self,money):
        pass

from overrides import overrides
class Bus(Car):
    @overrides
    def price(self,money):
        print('Bus car is ' , money)
    def price(self,money,tax):  #重载price方法
        print('Bus car is ' , money + tax)

bus = Bus()
bus.price(money=50)  #为啥不去找第一个price(self,money)函数?

运行直接报错:

TypeError: price() missing 1 required positional argument: 'tax'

后来发现:Python是动态类型语言,不支持java形式的重载。如果要重载,就用默认参数代替。为程序员着想的Python!

解决重载的方式,用默认值。

from abc import abstractclassmethod,ABCMeta
class Car(metaclass=ABCMeta):
    @abstractclassmethod
    def price(self,money):
        pass

from overrides import overrides
class Bus(Car):
    @overrides
    def price(self,money,tax = 10):  #重载price方法
        print('Bus car is ' , money + tax)

bus = Bus()
bus.price(money=50)  
bus.price(money=50,tax=30) 

overrides只要包含了父类的参数名money就不会报错。

Bus car is  60
Bus car is  80

学习时间:

半小时足够了


学习产出:

掌握
1、 java的抽象类实现方式,abc模块。抽象类和接口定义。
2、java式的overrides,记得子类必须包含父类的相同参数名
3、 python的重载方式,给参数赋默认值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值