1. 抽象类和接口之间的区别:
- 一个类可以实现任意多个接口,但它最多只能继承一个抽象类。
- 一个抽象类可以包含有若干个非抽象方法。但在接口中,无论一个方法是否被显式地声明为抽象的,接口中的方法都是抽象方法。
- 抽象类可以声明声明和使用字段,而接口却不行,尽管接口可以创建static final常量。
- 抽象类方法的可见性可以是public、protected、private或者修饰符(表示包内可见);而接口方法的可见性修饰符只能是public。
- 抽象类可以定义构造器,而接口不行。
- 继承一个抽象类的各类之间通常具有某种父子关系,而实现某个接口的各个类之间可以没有父子关系。
2. 对于下面这个定义的火箭仿真类接口的具体代码:
package com.oozinoz.simultation;
public interface RocketSim
{
abstract double getMass();
public double getThrust();
void setSimTime(double t);
}
下面说明正确的是(A,B,D)
- A.RocketSim接口中的三个方法都是抽象方法,尽管只有getMass()方法显式地声明为抽象的。
- B.RocketSim接口中的三个方法都是公有方法,尽管只有getThrust()方法被显式地声明为公有的。
- C.接口被声明为“公有接口”,即使省略了public关键字,它也应该是公有的。
- D.可以再创建一个接口,如RocketSimSolid接口,并扩展RocketSim接口。
- E.每个接口必须至少含有一个方法。
- F.接口可以声明实例字段,实现该接口的类也必须声明此字段。
- G.虽然不能实例化一个接口,但接口定义可以声明构造器方法,要求实现该接口的类必须提供具有指定参数的构造器。
答案解析:
接口中的方法总是抽象和公开的,无论是否被显式地声明为abstract及public。
接口的可见性受限于其所在的包,此处可见性修饰符为public,所以com.oozinoz.simulation包之外的其他类可以访问该接口。
一个接口可以扩展另一个接口,如List接口和Set接口都扩展了java.util包中的Collection接口。
不含方法的接口被称为“标记”接口,如Cloneable标记接口。有时候,位于类层次结构高层的方法,如Object.clone()方法,并不适合下面的各个子类。这时,我们可以创建一个标记接口,用于标识哪些子类需要这个方法,哪些子类不需要这个方法。Object类的子类中需要clone()方法的子类可以声明自己实现了Cloneable标记接口。
接口并不能声明实例字段,不过它可以通过声明static和final修饰的字段来声明常量。
接口不可以定义构造器方法。Java接口也无法要求实现它的类提供任何特定的构造器方法。
3. 请举出一个含有方法的接口例子,说明类在实现接口的方法时并不一定要执行若干操作或返回某个值。
当类被注册为一个监听器时就是一个例子;类仅仅为了自己而接收通知,而不是为了调用者。比如,我们也许想在MouseListener.mouseDragged()发生时采取动作,而对于相同监听者,MouseListener.mouseMoved()方法体是空白的。
4. 超越普通接口:
适当地使用Java接口能够简化并完善我们的程序设计,尽管有时候这种设计超出了普通接口的定义和使用方法。
如果期望:将类的外部接口适配客户期望的接口,可应用Adapter模式
如果期望:为一组类提供一个简单的接口,可以使用Facade模式
如果期望:为单个对象和群组对象定义共同的接口,可以使用Composite模式
如果期望:将实现与抽象相分离以便二者独立演化,可以使用Bridge模式
每种设计模式都旨在解决不同环境中的某个问题。面向接口的设计模式通常用于需要对一个类或者一组类的方法的访问方式进行定义或重定义的场合。例如,某个类拥有我们需要的功能,但它的方法名却不满足客户的期望,这时,我们就可以使用Adapter模式。