Java - interface01

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() {}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值