接口类

继承有两种用途:

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

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

# java : 面向对象编程
# 设计模式   —— 接口
# 接口类 : python原生不支持
# 抽象类 : python原生支持的
from abc import abstractmethod, ABCMeta


class Payment(metaclass=ABCMeta):  # 元类 默认的元类 type
    @abstractmethod
    def pay(self, money): pass  # 没有实现这个方法


# 规范 :接口类或者抽象类都可以
# 接口类 支持多继承,接口类中的所有的方法都必须不能实现 —— java
# 抽象类 不支持多继承,抽象类中方法可以有一些代码的实现 —— java
class Wechat(Payment):
    def pay(self, money):
        print('已经用微信支付了%s元' % money)


class Alipay(Payment):
    def pay(self, money):
        print('已经用支付宝支付了%s元' % money)


class Applepay(Payment):
    def pay(self, money):
        print('已经用applepay支付了%s元' % money)


def pay(pay_obj, money):  # 统一支付入口
    pay_obj.pay(money)


# wechat = Wechat()
# ali = Alipay()
app = Applepay()
# wechat.pay(100)
# ali.pay(200)
p = Payment()

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

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

抽象类

什么是抽象类

    与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

为什么要有抽象类

    如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类是从一堆中抽取相同的内容而来的,内容包括数据属性和函数属性。

  比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。

    从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。

  从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的

# 一切皆文件
import abc  # 利用abc模块实现抽象类


class All_file(metaclass=abc.ABCMeta):
    all_type = 'file'

    @abc.abstractmethod  # 定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        with open('filaname') as f:
            pass

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


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)

# 抽象类 : 规范
# 一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现
# 多继承的情况 由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中


# 抽象类还是接口类 : 面向对象的开发规范 所有的接口类和抽象类都不能实例化
# java :
# java里的所有类的继承都是单继承,所以抽象类完美的解决了单继承需求中的规范问题
# 但对于多继承的需求,由于java本身语法的不支持,所以创建了接口Interface这个概念来解决多继承的规范问题

# python
# python中没有接口类  :
#  python中自带多继承 所以我们直接用class来实现了接口类
# python中支持抽象类  : 一般情况下 单继承  不能实例化
#  且可以实现python代码

抽象类与接口类

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

抽象类是一个介于类和接口直接的一个概念,同时具备类和接口的部分特性,可以用来实现归一化设计 

在python中,并没有接口类这种东西,即便不通过专门的模块定义接口,我们也应该有一些基本的概念。

多态

多态指的是一类事物有多种形态

动物有多种形态:人,狗,猪

import abc


class Animal(metaclass=abc.ABCMeta):  # 同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass


class People(Animal):  # 动物的形态之一:人
    def talk(self):
        print('say hello')


class Dog(Animal):  # 动物的形态之二:狗
    def talk(self):
        print('say wangwang')


class Pig(Animal):  # 动物的形态之三:猪
    def talk(self):
        print('say aoao')

封装

封装】

         隐藏对象的属性和实现细节,仅对外提供公共访问方式。

【好处】 

1. 将变化隔离; 

2. 便于使用;

3. 提高复用性; 

4. 提高安全性;

【封装原则】

      1. 将不需要对外提供的内容都隐藏起来;

      2. 把属性都隐藏,提供公共方法对其访问。

私有变量和私有方法

在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)

# 广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种
# 只让自己的对象能调用自己类中的方法

# 狭义上的封装 —— 面向对象的三大特性之一
# 属性 和 方法都藏起来 不让你看见
class Person:
    __key = 123  # 私有静态属性

    def __init__(self, name, passwd):
        self.name = name
        self.__passwd = passwd  # 私有属性

    def __get_pwd(self):  # 私有方法
        return self.__passwd  # 只要在类的内部使用私有属性,就会自动的带上_类名

    def login(self):  # 正常的方法调用私有的方法
        self.__get_pwd()


alex = Person('alex', 'alex3714')
print(alex._Person__passwd)  # _类名__属性名
# print(alex.get_pwd())

# 所有的私有 都是在变量的左边加上双下划綫
# 对象的私有属性
# 类中的私有方法
# 类中的静态私有属性
# 所有的私有的 都不能在类的外部使用