• 【面向对象设计基础】接口


    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    a)使用场景:解决多重继承和Client需要多Service_Provider的支持。

    b)典型UML:

     

    image

     

    c)举例:薪水计算类的设计

    image

    不同的类别有不同的薪水计算方法,那么getSalary方法可以抽象到一个接口SalaryCalculator内,这样在Client进行调用时就会有多态的效果:

    image

    public interface SalaryCalculator {
          public double getSalary();
    }

    public class Employee {
           SalaryCalculator empType;
           String name;

           public Employee(String s, SalaryCalculator c) {
                 name = s;
                 empType = c;
           }
           public void display() {
                System.out.println("Name=" + name);
                System.out.println("salary= " + empType.getSalary());
           }
    }

     

    public class CategoryA implements SalaryCalculator {
         double baseSalary;
         double OT;

         public CategoryA(double base, double overTime) {
              baseSalary = base;
              OT = overTime;
         }
         public double getSalary() {
              return (baseSalary + OT);
         }
    }


    public class CategoryB implements SalaryCalculator {
          double salesAmt;
          double baseSalary;
          final static double commission = 0.02;
          public CategoryB(double sa, double base) {
             baseSalary = base;
             salesAmt = sa;
          }
         public double getSalary() {
             return (baseSalary + (commission * salesAmt));
         }
    }

     

    public class MainApp {
         public static void main(String [] args) {
         SalaryCalculator c = new CategoryA(10000, 200);
         Employee e = new Employee ("Jennifer”,c);
         e.display();
         c = new CategoryB(20000, 800);
         e = new Employee ("Shania”,c);
         e.display();
         }  
    }

     

     

    补充问题:

     

    1.为什么不支持多重继承:依据Sun的官方说法是,避免c++那样管理多重继承的层次关系而带来的复杂性(主要是在多态覆盖方法的时候采用的动态绑定机制),换成用接口来实现多重继承的大部分功能,一个类只能有一个父类,但可以有多个接口,以此对多继承提供了有力的支持。

     

    2.类中声明了系统可以提供的服务,类似于电路中的模块,但是不包含具体的实现。要表达“这是我要完成的任务,除此之外的细节不归我操心”时就用接口,例如:
    public interface Photographable{
    public void takePhoto();
    }

     

    3.接口中的成员变量默认都是public、static、final类型,因此必须被显示初始化。方法默认都是public、abstract。这是必须遵守的。

     

    4.接口没有构造方法,不能被实例化。与抽象类不同,接口不能提供任何具体实现。

     

    5.一个接口不能实现另一个接口,但是它可以继承多个接口。例如:
    public interface C extends A,B{
    void methodC();
    }

     

    6.接口必须通过类来实现它的抽象方法,例如:
    public class Glass implements Transparency{...}
    要是一个类要实现某个接口时,它必须实现接口中所有的抽象方法,除非这个类被定义为抽象类。若想要修改一个interface但影响太大又不能修改,则可以声明一个新的interface来继承原来的interface,并在其中增加操作。然后在使用的时候还面向父接口的同时,加上instanceof去判断,然后进行强制类型转换——这是个蹩脚的设计,来对待蹩脚的问题。


    7.允许定义接口类型的引用变量去引用实现了该接口的类的实例:
    Transparency t=new Glass();

     

    8.抽象类vs接口:这个问题最终归结于接口会不会变化、实现类是不是需要同时支持多个接口。抽象类与接口都是位于继承树的上方,都不能被实例化,都可以包含抽象方法。但前者可以提供默认实现,而后者则必须包含抽象方法。接口一旦确定就不能随意改动了,否则就带来太大的麻烦,所以接口一般被用来作为纯粹的规格描述。接口不要求它的实现类在语义上是同一种类型,所以要是非同类型的相同方法类型则使用接口,利于继承树的合理化。接口是系统最高层次的抽象类型。抽象类则是介于“抽象”和“实现”之间的半成品,抽象类力所能及地完成了部分实现。定制模式就是一种接口颗粒度细化的设计模式。抽象类是为了逻辑的封装,包含部分实现,同时要求子类必须按照某种方式实现。

     

    抽象类为类型建模,接口类为能力建模,同样都是is-a关系,前者表示类型上的,后者表示具备能力上的。

     

    9.针对接口设计的实质:接口用稳定性封装了易变化的部分,在实际的设计中,将稳定部分抽象为接口,然后将不稳定的具体实现设定为实现该接口的类,在方法中利用接口将变化封装起来作为传入参数,调用其中接口定义的方法即可,这个方法根本不知道具体的实现,只是作为封装变化的一个中转站。调用的时候直接传入一个想使用的具体实现类。

     

    10)注意:一个类继承了一个父类,并且实现了多个接口,extends放在implement前边.

     

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

  • 相关阅读:
    使用OpenCV进行相机标定
    近景摄影测量
    vmware安装操作系统
    mac下使用gnu gcc
    Collection of Boot Sector Formats for ISO 9660 Images
    java会不会出现内存泄露
    difference between http get and post
    Apache许可翻译
    项目持续集成工具
    常用的地图投影算法
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2822376.html
Copyright © 2020-2023  润新知