Python面向对象学习小结之四 抽象与接口类

继承有两种用途:

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)  

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能。

接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。

依赖倒置原则:
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程

在python中根本就没有一个叫做interface的关键字。

python中的abc模块

1.abc模块作用

Python本身不提供抽象类和接口机制,要想实现抽象类,可以借助abc模块。ABC是Abstract Base Class的缩写。

2.模块中的类和函数

abc.ABCMeta

这是用来生成抽象基础类的元类。由它生成的类可以被直接继承。

from abc import ABCMeta class MyABC: __metaclass__ = ABCMeta MyABC.register(tuple) assert issubclass(tuple, MyABC) assert isinstance((), MyABC)

上面这个例子中,首先生成了一个MyABC的抽象基础类,然后再将tuple变成它的虚拟子类。然后通过issubclass或者isinstance都可以判断出tuple是不是出于MyABC类。

另外,也可以通过复写__subclasshook__(subclass)来实现相同功能,它必须是classmethod

class Foo(object): def __getitem__(self, index): ... def __len__(self): ... def get_iterator(self): return iter(self) class MyIterable: __metaclass__ = ABCMeta @abstractmethod def __iter__(self): while False: yield None def get_iterator(self): return self.__iter__() @classmethod def __subclasshook__(cls, C): if cls is MyIterable: if any("__iter__" in B.__dict__ for B in C.__mro__): return True return NotImplemented MyIterable.register(Foo)

abc.abstractmethod(function)

表明抽象方法的生成器

class C:
    __metaclass__ = ABCMeta @abstractmethod def my_abstract_method(self, ...): ...

abc.abstractproperty([fget[,fset[,fdel[,doc]]]])

表明一个抽象属性

class C:
    __metaclass__ = ABCMeta @abstractproperty def my_abstract_property(self): ...

上例只是只读属性,如果是读写属性,可以如下:

class C:
    __metaclass__ = ABCMeta def getx(self): ... def setx(self, value): ... x = abstractproperty(getx, setx)


#一切皆文件,下面是个完整的抽象类继承的例子。
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
  all_type='file'
@abc.abstractmethod #定义抽象方法,无需实现功能
  def read(self):
  '子类必须定义读功能'
    pass

@abc.abstractmethod #定义抽象方法,无需实现功能
  def write(self):
  '子类必须定义写功能'
    pass

# class Txt(All_file):
# pass
#
# t1=Txt() #报错,子类没有定义抽象方法

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
  def read(self):
    print('文本数据的读取方法')

  def write(self):
    print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
  def read(self):
    print('硬盘数据的读取方法')

  def write(self):
    print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
  def read(self):
    print('进程数据的读取方法')

  def write(self):
    print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

猜你喜欢

转载自www.cnblogs.com/peterhuang1977/p/9273923.html
今日推荐