Java - interface01

来源:互联网 发布:金山数据恢复大师破解 编辑:程序博客网 时间:2024/05/06 11:11

interface关键字使abstract的概念向前迈进了一步。abstract允许人们在类中创建一个或多个没有具体实现的方法;interface则产生一个完全抽象的类,它的所有方法都没有具体实现(全部都只是声明)。你可以将interface看作“纯粹的”abstract class。它允许类的创建者为类建立其形式:有方法名、参数列表和返回类型,但是没有任何方法体。接口也可以包含字段,但是它们隐式为staticfinal的。接口只提供了形式,而未提供任何具体实现。

interface关键字和class关键字相同,可用public修饰(仅限于该接口在于其同名的文件中被定义),或者不添加修饰词使其只具有包访问权限。

implements关键字表示:interface只是它的外貌,但是现在我要声明它是如何工作的。

接口中的方法可以显示地声明为public的,但即使你不这么做,它们也是public的。因此,**当要实现一个接口时,在接口中被定义的方法也必须被定义为是public的;否则,它们将只能得到缺省的包访问权限,这样在方法被继承的过程中,其可访问权限就被降低了,这时Java编译器所不允许的。

/**
 * Title: Interfaces<br>
 * Description: 此例解释"接口"概念, 无任何功能接口<br>
 * Company: Augmentum Inc<br>
 * Copyright: (c) 2008 Thinking in Java<br>
 * 
@author Forest He
 * 
@version 1.0
 
*/

package com.augmentum.foresthe;
class Note {
    
private String noteName;
    
private Note (String noteName)this.noteName = noteName; }
    
public String toString() return noteName; }
    
public static final Note 
        MIDDLE_C 
= new Note("MIDDLE_C"),
        C_SHARP 
= new Note("C_SHARP"),
        B_FLAT 
= new Note("B_FLAT");
}

interface Instrument {
    
void play(Note note);
    String what();
    
void adjust();
}

class Wind implements Instrument {
    
public void play(Note note) { System.out.println("Wind.play() " + note.toString()); }
    
public String what() return "Wind"; }
    
public void adjust() {};
}

class Percussion implements Instrument {
    
public void play(Note note) { System.out.println("Percussion.play() " + note.toString()); }
    
public String what() return "Percussion"; }
    
public void adjust() {};
}

class Stringed implements Instrument {
    
public void play(Note note) { System.out.println("Stringed.play() " + note.toString()); }
    
public String what() return "Stringed"; }
    
public void adjust() {};
}

class Brass extends Wind {
    
public void play(Note note) { System.out.println("Brass.play() " + note.toString()); }
    
public void adjust() { System.out.println("Brass.adjust()"); }
}

class Woodwind extends Wind {
    
public void play(Note note) { System.out.println("Woodwind.play() " + note.toString()); }
    
public String what() return "Woodwind"; }
}

public class Music {
    
public static void tune(Instrument i) { i.play(Note.C_SHARP); }
    
public static void tuneAll(Instrument[] e) {
        
for(int i = 0; i < e.length; i++) tune(e[i]);
    }

    
public static void main(String[] args) {
        Instrument[] orchestra 
= {
          
new Wind(), new Percussion(), new Stringed(), new Brass(), new Woodwind()
        }
;
        tuneAll(orchestra);
    }

}

/*
 * 此例表明: 无论是将其向上转型为称为Instrument的普通类, 还是称为Instrument的抽象类, 或是称为Instrument的接口, 都不会有问题. 它们的行为是相同的.
 * 事实上你可以在tune()方法中看到, 没有任何依据来表明Instrument是一个普通类, 抽象类还是一个接口. 这样做的目的:为程序员提供了不同的方法来控制对象的创建和使用.
 
*/

Java中的多重继承

接口不仅仅只是一种纯粹形式的抽象类,他的目标比这更高。因为接口是根本没有任何具体实现的,也就是说,没有任何与接口相关的存储;因此也就无法阻止多个接口的组合。

在导出类中,不强制要求必须有一个抽象的or具体的(没有任何抽象方法)基类。如要要从一个非接口的类继承,那么只能从一个类去继承。其余的基元素都必须是接口。需要将所有的接口名都置于implements关键字之后,用逗号将它们一一隔开。可以继承任意多个接口,每一个都是一个独立类型,可以向上转型。

/**
 * Title: Multiple interfaces<br>
 * Description: 此例解释"接口"概念, 无任何功能接口<br>
 * Company: Augmentum Inc<br>
 * Copyright: (c) 2008 Thinking in Java<br>
 * 
@author Forest He
 * 
@version 1.0
 
*/

package com.augmentum.foresthe;

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 {
    
public static void f1(CanFight canfight) { canfight.fight(); }
    
public static void f2(CanSwim canswim) { canswim.swim(); }
    
public static void f3(CanFly canfly) { canfly.fly(); }
    
public static void f4(ActionCharacter actioncharacter) { actioncharacter.fight(); }
    
public static void main(String[] args) {
        Hero hero 
= new Hero();
        f1(hero);
        f2(hero);
        f3(hero);
        f4(hero);
    }

}

上例中Hero组合了具体类ActionCharacter和接口CanFightCanSwimCanFly。当通过这种方式将一个具体类和多个接口组合到一起时,这个具体类必须放在最前面,否则编译器会报错。

注意:CanFight接口与ActionCharacter类中的fight()方法的特征签名是一样的,而且在Hero中并没有提供fight()的定义。接口的规则是:可以从接口中继承,但是得到的只是另一个接口。如果想创建该新类型的对象,就必须有一个提供了其全部定义的类。即使Hero没有显式地提供fight()的定义,其定义也因ActionCharacter而随之而来,因此它是被自动提供的,这使得创建Hero对象成为了可能。

Adventure类中,可以看到有四个方法把上诉各种接口和具体类作为参数。当Hero对象被创建时,Hero对象可以被传递给这些方法中的任何一个,这意味着它依次被向上转型为每一个接口。

上例所展示的就是使用接口的核心原因:为了能够向上转型为多个基类型。次级原因则与使用抽象类相同:防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口。那么提出问题:我们该使用接口还是抽象类? 回答:接口为我们带来抽象类的好处,还带来多重继承的好处,所以如果要创建不带任何方法定义和成员变量的基类(没有方法实现,自然就不应该有成员变量),我们优先选择接口。只有在强制你必须要具有方法定义和成员变量的时候,才应该选择抽象类。

组合接口时的名字冲突:在打算组合的不同接口中使用相同的方法名通常会造成代码可读性的混乱(如上例的fight()方法),请尽量避免这种情况。

通过继承来扩展接口

通过继承,可以在接口中添加新的方法申明,也可以通过继承在新接口中组合数个接口。这两种情况都可以获得新的接口。

类和类之间的继承、接口与接口之间的继承使用extends;类和接口直接的继承使用implements

/**
 * Title: Extending an interface with inheritance<br>
 * Description: 此例解释"接口"概念, 无任何功能接口<br>
 * Company: Augmentum Inc<br>
 * Copyright: (c) 2008 Thinking in Java<br>
 * 
@author Forest He
 * 
@version 1.0
 
*/

package com.augmentum.foresthe;

interface Monster {
    
void menace(); //Monster:恶棍;menace:恐吓
}

interface DangerousMonster extends Monster {
    
void destory();
}

interface Lethal {
    
void kill(); //Lethal:killer
}

class DragonZilla implements DangerousMonster {
    
public void menace() {} //DragonZilla:凶暴的人
    public void destory() {}
}

interface Vampire extends DangerousMonster, Lethal {
    
void drinkBlood(); //Vampire:吸血鬼
}

class VeryBadVampire implements Vampire {
    
public void menace() {}
    
public void destory() {}
    
public void kill() {} {}
    
public void drinkBlood() {}
}
原创粉丝点击