Java接口之通过继承扩展接口
[来源] 达内 [编辑] 达内 [时间]2012-10-30
接口可以继承接口来创建新的接口,也可以将多个接口组合成一个新的接口
接口可以继承接口来创建新的接口,也可以将多个接口组合成一个新的接口,如下:
// : interfaces/ // Extending an interface with inheritance. interface Monster { void menace(); } interface DangerousMonster extends Monster { void destroy(); } interface Lethal { void kill(); } class DragonZilla implements DangerousMonster { public void menace() {} public void destroy() {} } interface Vampire extends DangerousMonster, Lethal { void drinkBlood(); } class VeryBadVampire implements Vampire { public void menace() {} public void destroy() {} public void kill() {} public void drinkBlood() {} } public class HorrorShow { static void u(Monster b) { b.menace(); } static void v(DangerousMonster d) { d.menace(); d.destroy(); } static void w(Lethal l) { l.kill(); } public static void main(String[] args) { DangerousMonster barney = new DragonZilla(); u(barney); v(barney); Vampire vlad = new VeryBadVampire(); u(vlad); v(vlad); w(vlad); } } // /:~
合并接口时的命名冲突
当组合接口的时候,方法的名称可能会冲突,如果是完全相同的接口方法则没有问题,对于重载的方法不能仅仅根据返回类型进行区分,也就是如果不同接口中的方法仅仅是返回类型不同的话,编译器会报错:
// : interfaces/ package interfaces; interface I1 { void f(); } interface I2 { int f(int i); } interface I3 { int f(); }
class C {public int f() { return 1; } }
class C2 implements I1, I2 { public void f() {} public int f(int i) { return 1; } // overloaded }
class C3 extends C implements I2 { public int f(int i) { return 1; } // overloaded }
class C4 extends C implements I3 { // Identical, no problem: public int f() { return 1 ; } }
// Methods differ only by return type:
// ! class C5 extends C implements I1 {}
// ! interface I4 extends I1, I3 {}
// /:~
接口中的域
因为接口中的域都是static和final,并且默认为public,因此接口是一个创建一系列静态常量的方便的地方。接口中声明的常量可以是空常量,但是他们可以通过非常量表达式进行初始化,因为这些字段是静态的,因此他们在类第一次加载的时候进行初始化,也就是在任何字段第一次被访问的时候:
// : interfaces/ // Initializing interface fields with // non-constant initializers. import java.util.*; public interface RandVals { Random RAND = new Random(47); int RANDOM_INT = RAND.nextInt(10); long RANDOM_LONG = RAND.nextLong() * 10; float RANDOM_FLOAT = RAND.nextLong() * 10; double RANDOM_DOUBLE = RAND.nextDouble() * 10; } ///:~ // : interfaces/Test import static net.mindview.util.Print.*; public class TestRandVals { public static void main(String[] args) { print(RandVals.RANDOM_INT); print(RandVals.RANDOM_LONG); print(RandVals.RANDOM_FLOAT); print(RandVals.RANDOM_DOUBLE); } } /* Output: 8 -32032247016559954 -8.5939291E18 5.779976127815049 *///:~
接口嵌套
接口可以嵌套在其他的类中或者其他的接口中,具有一些有趣的特征,如下:
// : interfaces/nesting/ package interfaces.nesting; class A { interface B { void f(); } public class BImp implements B { public void f() {} } private class BImp2 implements B { public void f() {} } public interface C { void f(); } class CImp implements C { public void f() {} } private class CImp2 implements C { public void f() {} } private interface D { void f(); } private class DImp implements D { public void f() {} } public class DImp2 implements D { public void f() {} } public D getD() { return new DImp2(); } private D dRef; public void receiveD(D d) { dRef = d; dRef.f(); } } interface E { interface G { void f(); } // Redundant "public": public interface H { void f(); } void g(); // Cannot be private within an interface: // ! private interface I {} } public class NestingInterfaces { public class BImp implements A.B { public void f() {} } class CImp implements A.C { public void f() {} } // Cannot implement a private interface except // within that interface’s defining class: // ! class DImp implements A.D { // ! public void f() {} // ! } class EImp implements E { public void g() {} } class EGImp implements E.G { public void f() {} } class EImp2 implements E { public void g() {} class EG implements E.G { public void f() {} } } public static void main(String[] args) { A a = new A(); // Can’t access A.D: // ! A.D ad = a.getD(); // Doesn’t return anything but A.D: // ! A.DImp2 di2 = a.getD(); // Cannot access a member of the interface: //! a.getD().f(); // Only another A can do anything with getD(): A a2 = new A(); a2.receiveD(a.getD()); } } // /:~
上面代码所显示出来的特性不需要当作语法记住,只需要记住接口的嵌套其可见型与一般的方法和成员的可见性相同,就可以很轻易的理解其使用方法。
接口和工厂
接口是作为一种多重实现的中间门槛,一种典型的用法就是工厂模式,这种模式中不是通过直接调用对象的构造函数来生成对象,而是通过在工厂对象中创建一个方法,返回符合接口规定的类型,从而将对象的实例化与客户端的代码解藕,如下面的代码:
// : interfaces/ import static net.mindview.util.Print.*; interface Service { void method1(); void method2(); } interface ServiceFactory { Service getService(); } class Implementation1 implements Service { Implementation1() {} // Package access public void method1() {print("Implementation1 method1");} public void method2() {print("Implementation1 method2");} } class Implementation1Factory implements ServiceFactory { public Service getService() { return new Implementation1(); } } class Implementation2 implements Service { Implementation2() {} // Package access public void method1() {print("Implementation2 method1");} public void method2() {print("Implementation2 method2");} } class Implementation2Factory implements ServiceFactory { public Service getService() { return new Implementation2(); } } public class Factories { public static void serviceConsumer(ServiceFactory fact) { Service s = fact.getService(); s.method1(); s.method2(); } public static void main(String[] args) { serviceConsumer( new Implementation1Factory()); // Implementations are completely interchangeable: serviceConsumer(new Implementation2Factory()); } } /* Output: Implementation1 method1 Implementation1 method2 Implementation2 method1 Implementation2 method2 */// :~