您的位置:首页 > 编程语言 > Java开发

【Java编程思想】(5)接口

2015-06-24 14:23 267 查看
1. 抽象类、接口

interface关键字使抽象的概念更向前迈进了一步。abstract关键字允许人们在类中创建一个或多个没有任何意义的方法——提供了接口部分,但是没有提供任何相应的具体实现,这些实现石油是由此类的继承者创建的。interface这个关键字产生一个完全抽象的类,它根本就没有提供任何具体实现。它允许创建者确定方法名、参数列表和返回类型,但是没有任何方法体。

接口只提供了形式,而未提供任何具体实现。抽象类中是可以有方法实现的,但是接口中全部没有方法体。

抽象类也可以没有抽象方法,即便如此,抽象类也不可以被实例化。

接口可以继承自多个接口。

但是,interface不仅仅是一个极度抽象的类,因为它允许人们通过创建一个能够被向上转型为多种基类的类型,来实现某种类似多重继变种的特性。

可以在interface关键字前面添加public关键字(但仅限于该接口与其同名的文件中被定义)。如果不添加public关键字,则它只具有包访问权限,这样它就只能在同一个包内可用。接口也可以包含域,但是这些隐式地是static和final的。

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

2. 完全解耦

创建一个能够根据所传递的参数对象不同而具有不同行为的方法,被称为策略设计模式。

3. 使用接口的核心原因

为了能够向上转型为多个基类型(以及由此而来的灵活性)。然而,使用接口的第二个原因确实与使用抽象基类相同:防止客户端程序员创建该类的对象,并确保这仅仅是建立一个接口。这就带来了一个问题:我们应该使用接口还是抽象类?如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。事实上,如果知道某事物应该成为一个基类,那么第一选择应该是使它成为一个接口。

4. 接口组合的名字冲突

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 int f(int i) {
		return 1;
	}

	public void f() {
	}

}

class C3 extends C implements I2 {
	public int f(int i) {
		return 1;
	}
}

class C4 extends C implements I3 {
	public int f() {
		return 1;
	}
}

//class C5 extends C implements I1 {
//}

//interface I4 extends I1, I3 {
//}

最后注释的内容是编译器报错的,因为不能通过方法的返回值来重载方法。

5. 适配接口

我们可以在任何现有类之上添加新的接口,所以这意味着让方法接受接口类型,是一种让任何类都可以对该方法进行适配的方式。这就是使用接口而不是类的强大之处。

6. 接口中的域

在接口中定义的域不能是“空final”,但是可以被非常量表达式初始化。

既然域是static的,它们就可以在类第一次被加载时初始化,这发生在任何域首次被访问时。当然这些域不是接口的一部分,它们的值被存储在该接口的静态存储区域内。

7. 嵌套接口

接口内部可以拥有其他接口,但不能有private的修饰的接口。

一个类不能实现其他类中的私有接口。

当实现某个接口时,并不需要实现嵌套在其内部的任何接口,而且,private接口不能在定义它的类之外被实现。

class A {

	private interface D {
		void f();
	}

	public class DImp2 implements D {
		public void f() {
		}
	}

	public D getD() {
		return new DImp2();
	}
}

public class TestInterface {
	public static void main(String[] args) {
		A a = new A();
		// 除了返回D之外,什么都没有返回,不能赋值给A.DImp2
		// A.DImp2 di2 = a.getD();
	}
}


8. 接口是实现多重继承的途径,而生成遵循某个接口的对象的典型方式就是工厂方法设计模式。这与直接调用构造器不同,我们在工厂对象上调用的是创建方法,而该工厂对象将生成接口的某个时间对象。理论上,通过这种方式,我们的代码将完全与接口的实现分离,这就是使得我们可以透明地将某个实现替换为另一个实现。

9. 任何抽象性都应该是应真正的需求而产生的。当必需时,你应该重构接口而不是到处添加额外级别的间接性,并由此带来的额外的复杂性。这种额外的复杂性非常显著,如果你让某人去处理这种复杂性,只是因为你意识到由于以防万一而添加了新接口,而没有其他更有说服力的原因,那么就应该质疑所有的设计了。

恰当的原则应该是优先选择类而不是接口。从类开始,如果接口的必须行变的非常明确,那么就进行重构。接口是一种重要的工具,但是它们容易被滥用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: