普通内部类的字段与方法, 只能放在类的外部层次上,
所以普通的内部类不能有static数据和static字段,
也不能包含嵌套类。但是嵌套类可以包含所有这些东西
使用内部类最吸引人的原因是:
每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经
继承了某个(接口的)实现,对于内部类都没有影响。
情况1:
必须在一个类中以某种方式实现2个接口,由于接口的灵活性。有2中选择
使用单一类, 或者使用内部类。 interface A{}
interface B{}
class X implements A, B{}
class Y implements B{
B makesB(){
return new B(){};
}
}
public class MultiInterfaces{
static void takesA(A a){}
static void takesB(B b){}
public static void main(String[] args){
X x = new X();
Y y = new Y();
takesA(x);
takesA(y);
takesB(x);
takesB(y.makeB());
}
}
从实现的观点来看,上面的例子并没有区别,都能正常运作。
如果拥有的是抽象类和具体的类,而不是接口,那就只能使用内部类
才能实现多重继承。
class D{}
abstract class E{}
class Z extends D{
E makesE(){
return new E(){};
}
}
public class MultiImplementation{
static void takesD(D d){}
static void takesE(E e){}
public static void main(String[] args){
Z z = new Z();
takesD(z);
takesE(z.makeE());
}
}
如果使用内部类,还可以获得其他一些特性:
1 内部类可以有多个实例,每个实例都有自己的状态信息,并且与外围类
对象的信息相互独立。
2 在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或
继承同一个类。
3 创建内部类对象的时刻并不依赖于外围类对象的创建。
4 内部类并没有令人迷惑的"is-a"关系,他就是一个独立的实体。
内部类与框架
public abstract class Event {
private long eventTime;
protected final long delayTime;
public Event(long delayTime){
this.delayTime = delayTime;
start();
}
public void start(){
eventTime = System.nanoTime() + delayTime;
}
public boolean ready(){
return System.nanoTime() >= eventTime;
}
public abstract void action();
}
public class Controller {
private List<Event> eventList = new ArrayList<Event>();
public void addEvent(Event e){
eventList.add(e);
}
public void run(){
while(eventList.size() > 0){
for(Event e : new ArrayList<Event>(eventList)){
if(e.ready()){
System.out.println(e);
e.action();
eventList.remove(e);
}
}
}
}
}
注意: 在目前的设计中并不知道Event到底做了上面。这证是次设计的光剑所在,
使变化的食物与不变的食物互相分离. 用我的话说, 变化向量,就是各种
不同的Event对象所具有的不同行为,而你通过创建不同的Event子类来表现
不同的行为。
这正是内部类要做的事情,内部类允许:
1) 控制框架的完整实现是由单个的类创建的,从而使得实现的细节被
封装了起来。内部类用来表示解决问题所必须的各种不同的action()
2) 内部类能够狠容易地访问外围类的任意成员,所以可以避免这种实现
变得笨拙。
public class GreenhouseControls extends Controller{
private boolean light = false;
public class LightOn extends Event{
public LightOn(long delayTime) {
super(delayTime);
}
public void action() {
light = true;
}
public String toString(){
return "Light is on";
}
}
public class LightOff extends Event{
public LightOff(long delayTime) {
super(delayTime);
}
public void action() {
light = false;
}
public String toString(){
return "Light is off";
}
}
private boolean water = false;
public class WaterOn extends Event{
public WaterOn(long delayTime){
super(delayTime);
}
public void action() {
water = true;
}
public String toString(){
return "Greenhouse water is on";
}
}
public class WaterOff extends Event{
public WaterOff(long delayTime){
super(delayTime);
}
public void action() {
water = false;
}
public String toString(){
return "Greenhouse water is off";
}
}
public class Bell extends Event{
public Bell(long delayTime) {
super(delayTime);
}
public void action() {
// addEvent(new Bell(dealyTime));
}
}
public class Restart extends Event{
private Event[] eventList;
public Restart(long delayTime, Event[] eventList) {
super(delayTime);
this.eventList = eventList;
for(Event e : eventList){
addEvent(e);
}
}
public void action() {
for(Event e : eventList){
e.start();
addEvent(e);
}
start(); //记录当前时间+时延时间
addEvent(this);
}
public String toString(){
return "Restarting system";
}
}
}