接口

理论上讲,接口(interface)类型应该是更加抽象的类型模板,但在添加了一此特性后,它也越来越像抽象类了,如Java8中的接口添加了方法的默认实现。不过,接口还是有一些类类型没有的特点,比如可以继承或实现多个接口,而类只能继承于一个超类。

接口与实现

接口中可以定义静态字段和方法,成员的访问级别是public。但有一点需要注意,静态字段必须指定一个值,这与抽象的初衷是相违背的。下面的代码,我们定义的IUnit接口中只使用了方法。

Java
public interface IUnit {
	String getName();
	void setName(String sName);
	void moveTo(int x, int y);
}

实际应用时,还需要类来实现接口,如下面的代码。

Java
public class CUnit implements IUnit {
	// 构造函数
	public CUnit(String sName) {
		name = sName;
	}
	// 属性
	private String name;
	public String getName() {
		return name;
	}
	public void setName(String sName) {
		name = sName;
	}
	// 方法
	public void moveTo(int x, int y) {
		System.out.printf("%s 移动到 (%d, %d)",name ,x,y);
	}
}

下面的代码,在main()方法中测试CUnit类的使用。

Java
public class Hello {
	public static void main(String[] args){
		IUnit unit = new CUnit("单位1");
		unit.moveTo(10, 99);
	}
}

代码执行结果如下图。

接口的继承

和类一样,接口同样可以通过继承进行复用,如下面的代码。

Java
public interface ITank extends IUnit {
	void attack(IUnit unit);
}

代码中,ITank接口继承于IUnit接口类型,并扩展了attack()方法。

下面的代码,创建了CTank类,并实现ITank接口,请注意,我们会利用CUnit类简化CTank类的实现。

Java
public class CTank extends CUnit implements ITank {
	//
	public CTank(String sName) {
		super(sName);
	}
	//
	public void attack(IUnit unit) {
		System.out.printf("%s 正在攻击 %s",getName(), unit.getName());
	}
}

下面的代码,在main()方法中测试CTank类的使用。

Java
public class Hello {
	public static void main(String[] args){
		ITank tank = new CTank("99A-001");
		tank.moveTo(10, 99);
		System.out.println();
		tank.attack(new CUnit("目标A"));
	}
}

代码执行结果如下图。

继承(实现)多个接口

与类的继承不同,接口可以继承多个接口,而类也可以同时实现多个接口,下面通过几个简单的接口和类进行测试。

首先是两个基本的接口I1和I2。

Java
public interface I1 {
	void method1();
	void method9();
}
Java
public interface I2 {
	void method2();
	void method9();
}

如果一个接口需要同时使用I1和I2接口,则可以通过继承实现,如下面的代码。

Java
public interface I3 extends I1,I2 {
}

下面的代码,通过C3类实现I3接口。

Java
public class C3 implements I3 {
	public void method1() {
		System.out.println("method1 is working");
	}
	public void method2() {
		System.out.println("method2 is working");
	}
	public void method9() { 
		System.out.println("method9 is working");
	}
}

下面,在main()方法测试C3类的使用。

Java
public class Hello {
	public static void main(String[] args){
		C3 c3a = new C3();
		c3a.method1();
		c3a.method2();
		c3a.method9();
	}
}

代码执行结果如下图。

I3接口和C3类的实现中,实际上是假设了一个前提,即method9()方法的功能是相同的;但是,如果I1和I2中的method9()方法功能不同,只是名称碰巧相同呢?如何在I3类和C3类中区分它们?

答案是没有太好的方案,只能通过不同的方法进行区分,如下面的代码,C3A类同样实现了I3接口。

Java
public class C3A extends C3 {
	// 重写I1接口method9()方法
	public void method9() {
		System.out.println("I1.method9 is working");
	}
	// 单独定义I2接口method9()方法
	public void i2_method9() {
		System.out.println("I2.method9 is working");
	}
}

这里通过两个方法来区分I1接口和I2接口中的method9()方法,下面的代码,我们在main()方法中C3A类的应用。

Java
public class Hello {
	public static void main(String[] args){
		C3A c3a = new C3A();
		c3a.method1();
		c3a.method2();
		c3a.method9();
		c3a.i2_method9();
	}
}

代码执行结果如下图。

本站内容均为原创作品,转载请注明出处,本页面网址为:http://caohuayu.com/chy/article/Article.aspx?code=cc001009