日期:2014-05-20  浏览次数:20756 次

抽象类,实例化,郁闷。
Calendar   calendar   =   Calendar.getInstance();   //①
    calendar.set(Calendar.YEAR,   Integer.parseInt(year1));   //②
    calendar.set(Calendar.MONTH,   Integer.parseInt(month1));

问题1:Calendar不是抽象类吗?抽象类不是不能实例化吗?   如①,为什么Calendar还能实例化?

问题2:如②,为了使用抽象类Calendar中的set()这个方法而去实例化一个对象,那这个类定义为抽象类还有什么意义?直接定义为普通实体类不就可以了吗?不解,望高人指教。

------解决方案--------------------
没错Calendar 是一个抽象类,它本身不能实例化,
LZ可否知道 抽象类可以可写方法实体?

这里Calendar用到了设计模式中的“工厂方法模式”。

Calendar.getInstance();正是实工厂方法,他返回一个类的实例,在这里是Calendar实现类的实例对象。LZ应该了解继承,知道子类可以当做父类一样被使用吧?
Calendar calendar = Calendar.getInstance();这句代码实际上是返回了一个Calendar子类的实例对象。然后把这个实例当做它的父类一样使用。

getInstance()方法内的代码类似:

public static Calendar getInstance(){
return new CalendarImp();//CalendarImp表示 Calendar 的实现类。
}

至于为什么要这样做及好处是什么?
这体实了面象接口编程的思想。

想一想你怎么使用这个Calendar?我们把使用Calendar的方法叫做客户端调用。
假设你在客户端代码直接使用Calendar 的实现类:
CalendarImp calendar = new CalendarImp();
一旦你有需要用另一个实现类替代这个,你需要修改这一句代码:
CalendarOtherImp calendar = new CalendarOtherImp ();
如果你的客户端代码中有N条这样的语句,你就需要修改N次。

而使用“工厂方法模式”:
Calendar calendar = Calendar.getInstance();
这样使你不需要了解Calendar 的具体实现类,一旦Calendar 的实现类发生了改变,或者有另外的实现类来代替它,你可以不用修改你的客户端代码。你只需要修改getInstance()方法让它返回另一个子类实现就可以了。

这样说LZ明白了吗?