且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-09-20 11:15:42

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

b)典型UML:

 

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

 

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

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

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

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

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/archive/2012/12/17/2822376.html,如需转载请自行联系原作者