zoukankan      html  css  js  c++  java
  • 有关"内部类"的三道面试题

    1.什么是内部类?Static Nested Class 和 Inner Class的不同。

    内部类就是在一个类的内部定义的类,内部类中不能定义静态成员(静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到一个类中而已,这么一点小事,你还要把它放到类内部的一个类中,过分了啊!提供内部类,不是为让你干这种事情,无聊,不让你干。我想可能是既然静态成员类似c语言的全局变量,而内部类通常是用于创建内部对象用的,所以,把“全局变量”放在内部类中就是毫无意义的事情,既然是毫无意义的事情,就应该被禁止),内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法体中,如下所示:

    1. public class Outer  
    2.   
    3. {  
    4.         intout_x  = 0;  
    5.   
    6.         publicvoid method()  
    7.               {  
    8.                Inner1inner1 = new Inner1();  
    9.                publicclass Inner2   //在方法体内部定义的内部类   
    10.                {  
    11.                       publicmethod()  
    12.                       {  
    13.                              out_x= 3;  
    14.                       }  
    15.                }  
    16.   
    17.                Inner2inner2 = new Inner2();  
    18.         }  
    19.   
    20.    
    21.         publicclass Inner1   //在方法体外面定义的内部类   
    22.         {  
    23.         }  
    public class Outer
    
    {
            intout_x  = 0;
    
            publicvoid method()
                  {
                   Inner1inner1 = new Inner1();
                   publicclass Inner2   //在方法体内部定义的内部类
                   {
                          publicmethod()
                          {
                                 out_x= 3;
                          }
                   }
    
                   Inner2inner2 = new Inner2();
            }
    
     
            publicclass Inner1   //在方法体外面定义的内部类
            {
            }
    
    1. }  
    }
    1.   
            


     

    在方法体外面定义的内部类的访问类型可以是public,protecte,默认的,private等4种类型,这就好像类中定义的成员变量有4种访问类型一样,它们决定这个内部类的定义对其他类是否可见;对于这种情况,我们也可以在外面创建内部类的实例对象,创建内部类的实例对象时,一定要先创建外部类的实例对象,然后用这个外部类的实例对象去创建内部类的实例对象,代码如下:

    1. Outer outer = new Outer();  
    2.   
    3. Outer.Inner1 inner1 = outer.new Innner1();  
    Outer outer = new Outer();
    
    Outer.Inner1 inner1 = outer.new Innner1();
    

    在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。

    对于这些细节,只要在eclipse写代码试试,根据开发工具提示的各类错误信息就可以马上了解到。

    在方法体内部还可以采用如下语法来创建一种匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无需为该子类定义名称:

    1. public class Outer  
    2.   
    3. {  
    4.         publicvoid start()  
    5.         {  
    6.                newThread(  
    7. new Runable(){  
    8.                              publicvoid run(){};  
    9. }  
    10. ).start();  
    11.         }  
    12. }  
    public class Outer
    
    {
            publicvoid start()
            {
                   newThread(
    new Runable(){
                                 publicvoid run(){};
    }
    ).start();
            }
    }
    

    最后,在方法外部定义的内部类前面可以加上static关键字,从而成为Static Nested Class,它不再具有内部类的特性,所有,从狭义上讲,它不是内部类。Static Nested Class与普通类在运行时的行为和功能上没有什么区别,只是在编程引用时的语法上有一些差别,它可以定义成public、protected、默认的、private等多种类型,而普通类只能定义成public和默认的这两种类型。在外面引用Static Nested Class类的名称为“外部类名.内部类名”。在外面不需要创建外部类的实例对象,就可以直接创建Static Nested Class,例如,假设Inner是定义在Outer类中的Static Nested Class,那么可以使用如下语句创建Inner类:

    Outer.Inner inner = new Outer.Inner();

    由于static Nested Class不依赖于外部类的实例对象,所以,static Nested Class能访问外部类的非static成员变量。当在外部类中访问Static Nested Class时,可以直接使用Static Nested Class的名字,而不需要加上外部类的名字了,在Static Nested Class中也可以直接引用外部类的static的成员变量,不需要加上外部类的名字。

    在静态方法中定义的内部类也是Static Nested Class,这时候不能在类前面加static关键字,静态方法中的Static Nested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。

    备注:首先根据你的印象说出你对内部类的总体方面的特点:例如,在两个地方可以定义,可以访问外部类的成员变量,不能定义静态成员,这是大的特点。然后再说一些细节方面的知识,例如,几种定义方式的语法区别,静态内部类,以及匿名内部类。

    2.内部类可以引用它的包含类的成员吗?有没有什么限制?

    完全可以。如果不是静态内部类,那没有什么限制!

    如果你把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码:

    1. class Outer  
    2.   
    3. {  
    4.  staticint x;  
    5.  staticclass Inner  
    6.  {  
    7.         voidtest()  
    8.         {  
    9.                syso(x);  
    10.         }  
    11.  }  
    12. }  
    class Outer
    
    {
     staticint x;
     staticclass Inner
     {
            voidtest()
            {
                   syso(x);
            }
     }
    }
    

    答题时,也要能察言观色,揣摩提问者的心思,显然人家希望你说的是静态内部类不能访问外部类的成员,但你一上来就顶牛,这不好,要先顺着人家,让人家满意,然后再说特殊情况,让人家吃惊。

    3.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

    可以继承其他类或实现其他接口。不仅是可以,而是必须!

  • 相关阅读:
    hdu 5154 拓扑排序
    CSS性能优化的8个技巧
    移动端性能监控方案Hertz
    箴言
    如何使网页的文字不能被复制
    flyio 的请求封装
    vue-cli3.0 环境变量与模式
    函数防抖和函数节流
    CSS世界中那些说起来很冷的知识
    vue多层次组件监听动作和属性
  • 原文地址:https://www.cnblogs.com/gxpblogs/p/3068056.html
Copyright © 2011-2022 走看看