1、内部类有效地实现了实现细节的隐藏,特别是声明为private的内部类,客户端程序员因为没有访问该类的权限,无法实现扩展。
2、除了定义在类中,内部类可以定义在各处:方法内、循环内、if条件判断内等任何作用域内,但是该作用域外无法访问该类。
3、我认为内部类的精髓在于向上转型。实现了某接口或者抽象类的内部类,其实用都是通过向上转型,客户端程序持有的其实是接口或者抽象类的类型。与普通的实现类不同的是,一般普通的实现类都是public类型,客户端能够访问该实现类,也就能随意的扩展(定义为final的类和方法除外),内部实现类无法访问,有效隐藏了实现细节。
其最吸引人的地方应该在于可以实现有限的多重继承。例如:
- abstract class A{};
- abstract class B{};
- class C extends A{
- B makeB(){
- return new B(){
- //TODO:可以直接有B的实现
- };
- };
- }
采取迂回的战术实现多重继承,其实是组合的一种代替,大可在先构造一个继承B的类D,然后把D组合到A中。
4、为什么普通的内部类不能拥有static的字段和方法?
我认为不是不能,而是没有必要。众所周知,static字段和方法在什么时候调入内存?在class第一次被load的时候。普通内部类什么情况下才会被load?普通内部类必须依赖于外部类对象,只有先实例化外部类对象,再实例化内部类,进而才能调用,这与普通的字段、方法何异?所以没有必要。(普通类什么时候第一次load,有2种情况:一是调用构造方法的时候,二是直接使用类调用静态字段和方法的时候)
5、为什么传入内部类的变量必须声明为final?
首先澄清一下,并非所有传入内部类的变量都得声明为final,只有必须在内部类的方法中使用的变量才有这个限制。有一种情况,内部类中只是调用基类的构造方法处理传入的变量,这种情况就不必声明为final。
回到问题上来,为什么final?先转到final这个关键字上来,它能够保证被修饰的变量必须被初始化。推而广之,即传入内部类的变量都能够被初始化。你可以反问一句,问什么必须保证传入内部类的变量都要初始化?那我就想反问一句,你会传入一个毫无意义的参数到一个方法中吗?如果你回答能,那我要恭喜你,你又得到重构的机会了。传入一个毫无意义的变量,还不如到内部类中自己定义一个呢,何必多次一举?
理清思路作答:传入到内部类的变量是即插即用的,所以必须是被初始化的,final就是来当这个担保人的。搞定!
6、一个疑问:内部类(非private)可以定义在接口内?这段代码调不通哦!!
- public interface ClassInInterface {
- void sunshine();
- class InInterface() implements ClassInInterface{
- public void sunshine(){
- System.out.println("Today is sunshine!");
- }
- public static void main(String[] args){
- new inInterface().sunshine();
- }
- }
- }