五、接口作为类型使用                                             
1.接口的使用                                                                               
       接口的使用与类的使用有些不同。
       在需要使用类的地方,会直接使用new关键字来构建一个类的实例进行应用:
              ClassA   a  =  new ClassA(); 这是正确的
       但接口不可以这样用,因为接口不能直接使用new关键字来构建实例。
              InterfaceA  a  = new InterfaceA(); 这是错误的
       接口在使用的时候要实例化相应的实现类。
              InterfaceA  a  =  new ImplementsA();    这是正确的
              下面就可以使用a.method()的方式来调用接口的方法了。
2.接口作为类型使用                                                                                    
接口作为引用类型来使用,任何实现该接口的类的实例都可以存储在该接口类型的变量中,通过这些变量可以访问类中所实现的接口中的方法,Java运行时系统会动态地确定应该使用哪个类中的方法,实际上是调用相应的实现类的方法。
 
示例如下:
public  class Test {
    public void test1(A a){
       a.doSth();
    }
    public static void main(String[] args) {
       Test t = new Test();
      
       A a = new B();
       t.test1(a);
    }
}
interface A{
    public int doSth(); 
}
class B implements A{
    @Override
    public int doSth() {
       System.out.println("now in B");
       return 123;
    }
}
运行结果:now in B
 
大家看到接口可以作为一个类型来使用,把接口作为方法的参数和返回类型。
 
五、接口和抽象类的选择                                            
    由于从某种角度讲,接口是一种特殊的抽象类,它们的渊源颇深,有很大的相似之处,所以在选择使用谁的问题上很容易迷糊。
很多人有过这样的疑问:为什么有的地方必须使用接口而不是抽象类,而在另一些地方,又必须使用抽象类而不是接口呢?或者说,在考虑Java类的一般化问题时,很多人会在接口和抽象类之间犹豫不决,甚至随便选择一种。
实际上接口和抽象类的选择不是随心所欲的。要理解接口和抽象类的选择原则,有两个概念很重要:对象的行为和对象的实现。如果一个实体可以有多种实现方式,则在设计实体行为的描述方式时,应当达到这样一个目标:在使用实体的时候,无需详细了解实体行为的实现方式。也就是说,要把对象的行为和对象的实现分离开来。既然Java的接口和抽象类都可以定义不提供具体实现的方法,在分离对象的行为和对象的实现时,到底应该使用接口还是使用抽象类呢?
在接口和抽象类的选择上,必须遵守这样一个原则:行为模型应该总是通过接口而不是抽象类定义。所以通常是:
(1) 优先选用接口,尽量少用抽象类。
选择抽象类的时候通常是如下情况:
(2) 需要定义子类的行为,又要为子类提供共性的功能。
 
 
练习实践                                    
程序1:                                                         
接口与Java的“多继承”
需求:定义多个接口,并实现多接口继承
目标:
1.         接口的含义;
2.         Java中多继承的接口实现;
程序:
//: Adventure.java
package com.useful.java.part3;
import java.util.*;
interface CanFight {
        void fight();
}
interface CanSwim {
        void swim();
}
interface CanFly {
        void fly();
}
class ActionCharacter {
        public void fight() {}
}
class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly {
        public void swim() {}
        public void fly() {}
}
public class Adventure {
        static void t(CanFight x) { x.fight(); }
        static void u(CanSwim x) { x.swim(); }
        static void v(CanFly x) { x.fly(); }
        static void w(ActionCharacter x) { x.fight(); }
        public static void main(String[] args) {
                Hero i = new Hero();
                t(i); // Treat it as a CanFight
                u(i); // Treat it as a CanSwim
                v(i); // Treat it as a CanFly
                w(i); // Treat it as an ActionCharacter
        }
}
说明:
1、  Java和C++不同,不存在多继承,如果非在实现多继承,那只有通过接口,变向实现;
2、  从中可以看到,Hero将具体类ActionCharacter同接口CanFight,CanSwim以及CanFly合并起来。按这种形式合并一个具体类与接口的时候,具体类必须首先出现,然后才是接口(否则编译器会报错)。请注意fight()的签名在CanFight接口与ActionCharacter类中是相同的,而且没有在Hero中为fight()提供一个具体的定义。
 
作业                                      
1.定义一个对象“交通工具”,并定义接口,说明交通工具可以移动。继承交通工具而产生汽车、飞机、轮船,并定义类来实现其移动的方法。
2.定义一个类来使用上面的接口
Java私塾跟我学系列——JAVA篇  网址:http://www.javass.cn  电话:010-68434236