什么是多态
多态,按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。
多态的目的:就是指不同的对象的,同状态下的,做出的不同表现形式
python中的鸭子类型
python中没有多态,但是可以用鸭子类型实现多态。
鸭子类型主要原因:python中参数是无类型的
init () 是一个最典型的鸭子类型 ( 多态)
class Cat(object): def say(self): print("i am a cat") class Dog(object): def say(self): print("i am a fish") class Company(object): def __init__(self, employee_list): self.employee = employee_list def __getitem__(self, item): return self.employee[item] def __len__(self): return len(self.employee) company = Company(["tom", "bob", "jane"]) class Duck(object): def say(self): print("i am a duck") animal_list = [Cat, Dog, Duck] for animal in animal_list: animal().say() dog = Dog() a = ["bobby1", "bobby2"] b = ["bobby2", "bobby"] name_tuple = ["bobby3", "bobby4"] name_set = set() name_set.add("bobby5") name_set.add("bobby6") a.extend() print(a)
接口类不能被实例化
在python里没有接口类这种数据类型,没有接口类专门的语法
但是 可以通过继承abc模块实现接口的功能
from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): # 接口类 @abstractmethod def pay(self,money): pass class Wechatpay(Payment): # 根据接口类的规范编程 def pay(self,money): print('微信支付了%s元'%money) p = Wechatpay() p.pay(6)
#我们去检查某个类是否有某种方法 class Company(object): def __init__(self, employee_list): self.employee = employee_list def __len__(self): return len(self.employee) com = Company(["bobby1","bobby2"]) print(hasattr(com, "__len__")) class A: pass class B: pass #我们在某些情况之下希望判定某个对象的类型 from collections.abc import Sized isinstance(com, Sized) b = B() print(isinstance(b, A)) # print(len(com)) #我们需要强制某个子类必须实现某些方法 #实现了一个web框架,集成cache(redis, cache, memorychache) #需要设计一个抽象基类, 指定子类必须实现某些方法 #如何去模拟一个抽象基类 import abc from collections.abc import * class CacheBase(metaclass=abc.ABCMeta): @abc.abstractmethod def get(self, key): pass @abc.abstractmethod def set(self, key, value): pass # class CacheBase(): # def get(self, key): # raise NotImplementedError # def set(self, key, value): # raise NotImplementedError # class RedisCache(CacheBase): def set(self, key, value): pass # redis_cache = RedisCache() # redis_cache.set("key", "value")
二. 接口隔离原则
from abc import ABCMeta,abstractmethod class FlyAnimal(metaclass=ABCMeta): @abstractmethod def fly(self): print(11111) class SwimAnimal(metaclass=ABCMeta): @abstractmethod def swim(self): pass class WalkAnimal(metaclass=ABCMeta): @abstractmethod def walk(self): pass class Swan(SwimAnimal,WalkAnimal,FlyAnimal): # 飞 def fly(self):pass # 游泳 def swim(self):pass # 走 def walk(self):pass class Qq(SwimAnimal,WalkAnimal): def swim(self):pass # 走 def walk(self):pass class Bird(FlyAnimal,WalkAnimal): # 飞 def fly(self):pass # 走 def walk(self):pass Swan() 接口隔离原则
三. 抽象类
抽象类 规范一个类的类
在python里 抽象类和接口类 没区别
在java里 有区别
java的接口规定里面的方法一定不能实现(一句代码也不能写)
抽象类 单继承
无论接口类 还是抽象类 其实都是一种面向对象编程的开发规范
只是在接口类或者抽象类中 去约束继承它的子类必须实现某些方法
对于java代码来说:如果发生多继承(类似上面接口隔离原则) 那么一定是接口类 且里面的方法都不能实现
如果在方法里有了实现 那么一定是单继承 的抽象类
但是对于python来说 就没有这些约束
因为python没有接口的概念
对于类的继承 没有多继承的限制
实际上abc模块是帮我实现抽象类的方法,只是我们用它来模仿接口类的效果了
在python中,只要metaclass = ABCMeta 定义了抽象方法(@abctractmethod)
这个类就不能被实例化
你可以说他是一个抽象类
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/9350692.html