1.完善多重继承

  1. 欲学Java,必黑C++。Java设计者原来想用C++开发一个内部项目,可是发现C++实在太烂,API不够全面,缺少垃圾回收机制,在移植的安全性和多线程上支持不够好。于是决定开发一种新的编程语言来解决这些问题,Java由此诞生。所以同学们,如果想学好Java,请跟我大喊C++是傻X。
  2. C++作为比较早期的面向对象编程语言,摸着石头过河,不幸的当了炮灰。比如多重继承,Java是不太欢迎继承的。因为继承耦合度太高。比如你是一个人,你想会飞,于是就继承了鸟这个类,然后你顺便拥有了一对翅膀和厚厚的羽毛,可这些玩意你并不需要。所以Java发明了接口,以契约的方式向你提供功能。想想看,你的程序里成员变量会比函数多吗?况且多重继承会遇到死亡菱形问题,就是两个父类有同样名字的函数,你继承谁的呢?其实C++也可以做到这些,那就是定义没有成员变量的纯虚类,而且所有函数都是纯虚函数。可是这些都是要靠程序员自己把握,并没有把这些功能集成到类似Interface这样的语法里。
  3. 所以Java只支持单重继承,想扩展功能,去实现接口吧。很快Java的设计者就发现了他们犯了矫枉过正的错误,多重继承还是有一定用处的。比如每一个人都是同时继承父亲和母亲两个类,要不然你的身体里怎么能留着父母的血呢?Java内部类应运而生。

2.实现事件驱动系统

  1. 用来开发GUI的Java Swing使用了大量内部类,主要用来响应各种事件。Swing的工作就是在事件就绪的时候执行事件,至于事件具体怎么做,这由事件决定。这里面有两个问题:1.事件必须要用到继承2.事件必须能访问到Swing。多说无用,上代码。        
package cn.vobile;

import java.util.ArrayList;
import java.util.List;

abstract class Event {

	private long eventTime;
	protected final long delayTime;

	public Event(long delayTime) {
		this.delayTime = delayTime;
		start();
	}

	public void start() {
		eventTime = System.currentTimeMillis() + delayTime;
	}

	public boolean ready() {
		return System.currentTimeMillis() >= eventTime;
	}

	public abstract void action();
}

abstract 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 event : new ArrayList<Event>(eventList)) {
				if (event.ready()) {
					event.action();
					eventList.remove(event);
				}
			}
		}
	}
}

class GreenHouseController extends Controller {

	private boolean light = false;

	public class LightOn extends Event {

		public LightOn(long delayTime) {
			super(delayTime);
		}

		@Override
		public void action() {
			light = true;
			System.out.println("light is on");
		}
	}

	public class LightOff extends Event {

		public LightOff(long delayTime) {
			super(delayTime);
		}

		@Override
		public void action() {
			light = false;
			System.out.println("light is off");
		}
	}

}

public class Farm {

	public static void main(String[] args) {
		GreenHouseController ghc = new GreenHouseController();
		ghc.addEvent(ghc.new LightOn(1));
		ghc.addEvent(ghc.new LightOff(2000));
		ghc.run();
	}
}

3.闭包和回调

function Outer(){
    var i=0;
    function Inner(){
        alert(++i);
    }
    return Inner;
}
var test = Outer();
  1. JavaScript 中闭包的产生是由于 JavaScript 中允许内部 function,也就是在一个 function 内部声明的 function 。内部 function 可以访问外部 function 中的局部变量、传入的参数和其它内部 function 。当内部 function 可以在包含它的外部 function 之外被test引用时,就形成了一个闭包。这个时候,即便外部 function 已经执行完成,该内部 function 仍然可以被执行,并且其中所用到的外部 function 的局部变量、传入的参数等仍然保留外部 function 执行结束时的值。
    内部类是面向对象的闭包,因为它不仅包含创建内部类的作用域的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括private成员。一般使用一个库或类时,是你主动调用人家的API,这个叫Call,有的时候这样不能满足需要,需要你注册(注入)你自己的程序(比如一个对象),然后让人家在合适的时候来调用你,这叫Callback。
public interface CallBack {

	void print();
}
class Printer {

	private CallBack callBack;
	private String id;

	public void setCallBack(CallBack callBack) {
		this.callBack = callBack;
	}

	public void execute() {
		callBack.print();
	}
}

public class PrintHandler {

	public static void main(String[] args) {
		Printer printer = new Printer();
		printer.setCallBack(new CallBack() {

			@Override
			public void print() {
				System.out.println("print successfully");
			}
		});
		printer.execute();
	}
}

  1. 当父类和实现的接口出现同名函数时,你又不想父类的函数被覆盖,回调可以帮你解决这个问题。
public interface Util {

	void test();
}

class Base {

	public void test() {
		System.out.println("base test");
	}
}

public class Sub extends Base {

	private class Closure implements Util {

		@Override
		public void test() {
			System.out.println("Sub test");
		}
	}

	public Util getUtil() {
		return new Closure();
	}

	public static void main(String[] args) {
		Sub sub = new Sub();
		sub.test();
		sub.getUtil().test();
	}
}