面向对象三大特性——继承高阶(接口和抽象类)

1、接口(Interface)

  在C++、JAVA等程序开发时,每每会利用到接口。接口其实就是:本身提供给使用者来调用本身功能的方式\方法\入口。java

=================第一部分:Java 语言中的接口很好的展示了接口的含义: IAnimal.java
/*
* Java的Interface接口的特征:
* 1)是一组功能的集合,而不是一个功能
* 2)接口的功能用于交互,全部的功能都是public,即别的对象可操做
* 3)接口只定义函数,但不涉及函数实现
* 4)这些功能是相关的,都是动物相关的功能,但光合做用就不适宜放到IAnimal里面了 */

package com.oo.demo;
public interface IAnimal {
    public void eat();
    public void run(); 
    public void sleep(); 
    public void speak();
}

=================第二部分:Pig.java:猪”的类设计,实现了IAnnimal接口 
package com.oo.demo;
public class Pig implements IAnimal{ //以下每一个函数都须要详细实现
    public void eat(){
        System.out.println("Pig like to eat grass");
    }

    public void run(){
        System.out.println("Pig run: front legs, back legs");
    }

    public void sleep(){
        System.out.println("Pig sleep 16 hours every day");
    }

    public void speak(){
        System.out.println("Pig can not speak"); }
}

=================第三部分:Person2.java
/*
*实现了IAnimal的“人”,有几点说明一下: 
* 1)一样都实现了IAnimal的接口,但“人”和“猪”的实现不同,为了不太多代码致使影响阅读,这里的代码简化成一行,但输出的内容不同,实际项目中同一接口的同一功能点,不一样的类实现彻底不同
* 2)这里一样是“人”这个类,但和前面介绍类时给的类“Person”彻底不同,这是由于一样的逻辑概念,在不一样的应用场景下,具有的属性和功能是彻底不同的 */

package com.oo.demo;
public class Person2 implements IAnimal { 
    public void eat(){
        System.out.println("Person like to eat meat");
    }

    public void run(){
        System.out.println("Person run: left leg, right leg");
    }

    public void sleep(){
        System.out.println("Person sleep 8 hours every dat"); 
    }

    public void speak(){
        System.out.println("Hellow world, I am a person");
    } 
}

=================第四部分:Tester03.java
package com.oo.demo;

public class Tester03 {
    public static void main(String[] args) {
        System.out.println("===This is a person==="); 
        IAnimal person = new Person2();
        person.eat();
        person.run();
        person.sleep();
        person.speak();

        System.out.println("\n===This is a pig===");
        IAnimal pig = new Pig();
        pig.eat();
        pig.run();
        pig.sleep();
        pig.speak();
    } 
}

 java中的interface
java中interface

一、使用接口的好处

  接口提取了一群类共同的函数,能够把接口当作一个函数的集合。而后让子类去实现接口中的函数。这样作得好处也就是实现了归一化。python

2、归一化

  归一化:只要是基于同一个接口实现的类,那么这些类产生的对象在使用时,从用法来讲是同样的。linux

一、归一化的好处

  1)让使用者无需关心对象的类,只须要知道这些对象都具有某些功能便可,下降使用难度。微信

  2)让高层的外部使用者能够不加区分地处理全部接口兼容的对象集合。网络

1、就好象linux的泛文件概念同样,全部东西均可以当文件处理,没必要关心它是内存、磁盘、网络仍是屏幕(固然,对底层设计者,固然也能够区分出“字符设备”和“块设备”,而后作出针对性的设计:细致到什么程度,视需求而定)。

二、再好比:咱们有一个汽车接口,里面定义了汽车全部的功能,而后由本田汽车的类,奥迪汽车的类,大众汽车的类,他们都实现了汽车接口,这样就好办了,你们只须要学会了怎么开汽车,那么不管是本田,仍是奥迪,仍是大众咱们都会开了,开的时候根本无需关心我开的是哪一类车,操做手法(函数调用)都同样
接口兼容处理例子

3、python中实现接口

  在python中并无interface关键字,若是想去模仿接口概念,有两种方法:app

方法一:借助第三方模块 http://pypi.python.org/pypi/zope.interfaceide

方法二:使用继承。函数

一、继承的两种用途

  1)继承基类的方法,并作出本身的改变或扩展(代码重用)。工具

  实际这种用法意义不大,甚至每每是有害的,由于它会使得子类和基类出现强耦合微信支付

  2)声明某个子类兼容于某基类,定义一个接口类,接口类中定义一些接口名(函数名)且并未实现接口功能,子类继承接口类,并实现接口的功能。又称为接口继承

# 正常实现调用
class Applepay:
    def pay(self,money):
        print('apple pay 支付了%s' %money)

class Alipay:
    def pay(self,money):
        print('支付宝  支付了%s' %money)

def payment(pay_obj,money):  #实例化的另外一种调用,这个方法让实例化的时候按照payment调用:就像下面的payment(apple1,200)
        pay_obj.pay(money)

apple1 = Applepay()
# apple1.pay(200)
payment(apple1,200)
"""
apple pay 支付了200
"""
正常实现调用
# 2.有时候写的时候会把方法写错,本身定义一个主动报错
# 接口初成:手动报异常:NotImplementedError来解决开发中遇到的问题
class Payment:
    def pay(self):
        raise NotImplementedError  #主动让程序报错

class Wechatpay(Payment): #微信支付
    def pay(self,money):
        print('微信支付了%s元',money)

class QQchatpay(Payment): #QQ支付
    def fuqian(self,money):
        print('QQ支付了%s元',money)

p = Wechatpay()
p.pay(200)   #不报错  # 微信支付了%s元 200
q = QQchatpay()  
q.pay()  #报错
主动报错
# 3.借用abc模块来实现接口
#接口类(就是为了提供标准,约束后面的子类)
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        pass

class Wechatpay(Payment):
    def fuqian(self,money):
        '''实现了pay的功能,可是方法名字不同'''
        print('微信支付了%s元'%money)

class Alipay:
    def pay(self,money):
        print('支付宝  支付了%s' %money)

# p = Wechatpay() #报错了(由于上面定义了一个接口类,接口类里面
# 定义了一个pay方法,而在下面的Wechatpay方法里没有pay方法,不能
# 调用,在接口类里面约束一下,接口类里的pay方法里面不能写其余,直接pass)
a = Alipay()
a.pay(200)
"""
支付宝  支付了200
"""
# p = Payment() #接口类不能被实例化
abc模块实现接口

  由上面的例子能够归结,接口也就是作约束,让下面的类的方法都按照接口类中给出的方法去定义。若是接口类里有的方法类里面没有,则这个类不能被实例化。而abc模块的使用,则说明了接口和抽象类的关联性。

4、抽象类

一、抽象类概念

  抽象类每每用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不一样,可是本质上相同的具体概念的抽象。在面向对象的概念中,全部的对象都是经过类来描绘的,可是反过来,并非全部的类都是用来描绘对象的,若是一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

二、抽象类特色

  抽象类与普通类的特殊之处就是只能被继承抽象类是不完整的,它只能用做基类),不能被实例化

三、抽象类用处

  在面向对象方法中,抽象类主要用来进行类型隐藏和充当全局变量的角色。下降使用者的使用复杂度,统一标准。

四、抽象类的实现

  python的abc模块中定义了抽象类的metaclass类ABCMeta,以及抽象方法装饰器abstractmethod, abstractclassmethod, abstractstaticmethod,抽象property装饰器abstractproperty等。能够基于这些工具来实现本身的抽象类。

import abc    #利用abc模块实现抽象类

class Animal(metaclass=abc.ABCMeta):  # 相似接口,只定义规范,不实现具体的代码
    @abc.abstractclassmethod
    def run(self):
        pass

    @abc.abstractclassmethod
    def eat(self):
        pass

# 尝试实例化抽象类:结果失败
# animal = Animal()
# TypeError: Can't instantiate abstract class Animal with abstract methods eat, run

class People(Animal):
    def run(self):  # 不符合规范,不容许实例化
        print('people is walking')

    def eat(self):
        print('people is eating')

class Pig(Animal):
    def run(self):
        print('Pig is running')

    def eat(self):
        print('Pig is eating')

class Dog(Animal):
    def run(self):
        print('Dog is zouing')

    def eat(self):
        print('Dog is eating')

peo1 = People()
pig1 = Pig()
Dog1 = Dog()

peo1.eat()
pig1.eat()
Dog1.run()
"""
people is eating
Pig is eating
Dog is zouing
"""
抽象类实现
#一切皆文件
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)
一切皆文件

5、抽象类与接口

  抽象类表示该类中可能已经有一些方法的具体定义,可是接口就仅仅只能定义各个方法的界面(方法名,参数列表,返回类型),并不关心具体细节。 

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

  抽象类是一个介于类和接口之间的一个概念,同时具有类和接口的部分特性,能够用以实现归一化设计。

一、抽象类和接口相同点

  一、不能实例化;

  二、包含未实现的方法声明;

  三、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是全部成员(不只是方法包括其余成员)

二、不一样点

  一、类能够实现无限个接口,但仅能从一个抽象(或任何其余类型)类继承,从抽象类派生的类仍可实现接口,从而得出接口是用来解决多重继承问题的。

  二、抽象类当中能够存在非抽象的方法,可接口不能。

  三、抽象类中的成员变量能够被不一样的修饰符来修饰,可接口中的成员变量默认的都是静态常量(static final)。

  四、抽象类是对象的抽象,然而接口是一种行为规范。

相关文章
相关标签/搜索