A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Liwuyiuxxx 初级黑马   /  2014-9-18 09:40  /  4082 人查看  /  21 人回复  /   2 人收藏 转载请遵从CC协议 禁止商业使用本文

10黑马币

最佳答案

查看完整内容

内部类与外部类之间的成员互相访问 内部类可以访问外部类的任何成员,包括private成员。 外部类访问内部类的成员需要创建内部类的对象,之后可以访问内部类的任何成员,包括private成员,需要注意的是成员内部类不可以有静态成员。 当外部类的成员和内部类的成员重名时单单用this是区分不了的。在内部类中访问外部类的成员时可以用如下语法区分 .this.; 局部内部类 内部类定义在方法中成为局部内部类,只在局部有效。该类只 ...

21 个回复

倒序浏览
内部类与外部类之间的成员互相访问  内部类可以访问外部类的任何成员,包括private成员。  外部类访问内部类的成员需要创建内部类的对象,之后可以访问内部类的任何成员,包括private成员,需要注意的是成员内部类不可以有静态成员。  当外部类的成员和内部类的成员重名时单单用this是区分不了的。在内部类中访问外部类的成员时可以用如下语法区分  <外部类类名>.this.<外部类中需要被访问的成员名>;   局部内部类  内部类定义在方法中成为局部内部类,只在局部有效。该类只为所在的方法块服务。  局部内部类和成员内部类一样可以访问外围类的所有成员,但是不可以访问同在一个局部块的普通局部变量。如果要访问,此局部变量要被声明称final的。  代码块结束后普通的局部变量会消亡,而创建的局部内部类对象并不会随着语句块的结束而消亡。final的局部变量的存储方式和普通的局部变量不同,其不会因为语句块的结束而消失,还会长期存在,因此可以被局部内部类访问。

点评

确实 之前看过些资料 说的是都会消亡 只是jdk动了手脚 把final的值复制到内部类中 不知道是不是真这样  发表于 2014-10-2 07:33
在JDK1.8中, 不再要求这个局部变量必须是final型的了.  发表于 2014-9-25 00:03
"final的局部变量的存储方式和普通的局部变量不同"----这个说法不准确. final局部变量也是分配到栈空间的, 等到函数执行完时, 这个final变量也消亡的.   发表于 2014-9-25 00:02
回复 使用道具 举报
public class InnerClass {
        int i = 5;
        String string = "Hello";
// 方法中的局部内部类访问方法中的成员变量时,此变量要用final修饰,
        // static方法中的局部内部类访问外部类中的成员变量时,变量要用static修饰
        // 非static方法中的局部内部类访问外部类中的成员变量时,变量不必要要用static修饰
        void TestInnerClass() {
                final int x = 100;
                class InnerofInnerClass {

                        void Test1() {
                                System.out.println(x);
                                System.out.println(i);
                                System.out.println(string);
                        }
                }
        }
}

/*
* 非静态方法访问静态内部类的成员 先“外部类.内部类”访问至内部类。 若访问静态成员, 则需先new再访问;若访问非静态成员,则可直接访问。
*/
class Outter {
        void Test1() {
                Outter.Inner2 inner2 = new Outter.Inner2();
                System.out.println(inner2.i);
                System.out.println(inner2.string);
                System.out.println(Outter.Inner2.string);
        }

        static class Inner2 {
                int i = 5;
                static String string = "Hello";
        }
}

/*
* 静态方法访问非静态内部类的成员 静态方法Test2访问非静态Inner1需先new外部类; 继续访问非静态成员i需先new 内部类 所以访问规则为:new
* Outter().new Inner1().i。
*/
class Outter1 {
        static void Test2() {
                System.out.println(new Outter1().new Inner1().i);
        }

        class Inner1 {
                int i = 5;
                // static String string = "Hello"; 定义错误!
        }
}

/*
* 外部类访问内部类 大方向:因为将内部类理解为外部类的一个普通成员,所以外面的访问里面的需先new一个对象。 非静态方法访问非静态内部类的成员: new
* 内部类对象
*/
class Outter2 {
        void Test1() {
                System.out.println(new Inner1().i);
        }

        class Inner1 {
                int i = 5;
                // static String string = "Hello"; 定义错误!
        }
}

/*
* 内部类又称为嵌套类,可以把内部类理解为外部类的一个普通成员。 内部类访问外部类
* 里面的可以自由访问外面的,规则和static一样。(访问非静态时必须先创建对象) 具体如下: 非静态内部类的非静态方法 直接访问
*/
class Outter5 {
        int i = 5;
        static String string = "Hello";

        class Inner1 {
                void Test1() {
                        System.out.println(i);
                        System.out.println(string);
                }
        }
}

/*
* 静态内部类的非静态方法 因为静态方法访问非静态外部成员需先创建实例,所以访问i时必须先new外部类。
*/
class Outter4 {
        int i = 5;
        static String string = "Hello";

        static class Inner2 {
                void Test1() {
                        System.out.println(new Outter4().i);
                        System.out.println(string);
                }
        }
}

/*
* 静态内部类的静态方法 规则如上
*/
class Outter3 {
        int i = 5;
        static String string = "Hello";

        static class Inner2 {
                static void Test2() {
                        System.out.println(new Outter3().i);
                        System.out.println(string);
                }
        }
}

/*
* 非静态方法访问非静态内部类的成员 先“外部类.内部类”访问至内部类,再new即可访问静态成员。
*/
class Outter6 {
        void Test1() {
                Outter6.Inner1 inner2 = new Outter6.Inner1();
                System.out.println(inner2.i);
        }

        class Inner1 {
                int i = 5;
                // static String string = "Hello"; 定义错误!
        }
回复 使用道具 举报
内部类可以直接访问外部类中的成员,而外部类要想访问内部类必须实例化内部类的对象才可以访问.
回复 使用道具 举报
内部类本质上就是外部类的一个成员,享有成员一样的共性。
就好比抽象类,也是类,具有类的所有共性。然后因为abstract所以具有了自己的特性。
所以内部类具有成员的一切共性,也具有类的一切共性,同时也具有自己的一些特性。

类的成员之间可以互相访问,所以这个内部类也可以访问外部类的成员。封装的目的就是为了代码的复用、增强安全性、实现模块化等,其实内部类嵌入到里面也是为了这个目的。不能说是破坏了这个封装原则吧。

内部类也有说内嵌类的,这种内嵌类在SDK中还是不少的。JDK中记得不太清楚了,ADK(安卓的SDK)中比如有LinearLayout.LayoutParames、ViewGroup.LayoutParames、SharedPreferences.Editor等都是内部类的体现。
回复 使用道具 举报
1.内部类可以直接访问外部类中的成员,包括私有
      原因:因为在内部类中持有一个外部类的应用,格式:外部类.this
class Outer {
     private int x = 1;
     class Inner {
         int x = 2;
         public void seeOuter() {
              int x = 3;
              System.out.println(x);
              System.out.println(this.x);
              System.out.println(Outer.this.x);
        }
     }  
}

2.外部类要访问内部类,必须建立内部类对象
A.从外部类的非静态方法中访问内部类
class Outer {
  private int x = 1;
public void seeInner() {
   Inner in = new Inner();
   in.seeOuter();
  }
class Inner {
   public void seeOuter() {
    System.out.println(x);
   }
  }
}
B、从外部类的静态方法中访问内部类
class Outer {
  private int x = 1;
  class Inner {
   public void seeOuter() {
   System.out.println(x);
   }
  }
  public static void seeInner(){
   Outer.Inner inner  = new Outer().new Inner(); //1
   //如果把1位置的访问方式换成 new Inner().seeOuter() 必须保证Inner是静态的
   inner.seeOuter();
  }
}
C、在外部其它类中访问内部类
class Outer {
  private int x = 1;
  class Inner {
   public void seeOuter() {
    ystem.out.println(x);
   }
  }
}
public class Touter{
  public static void main(String[] args){
   Outer.Inner inner = new Outer().new Inner();
   inner.seeOuter();
  }

}
对比:在外部类的非静态方法中访问内部类:Inner in = new Inner();
      在外部类的静态方法中访问内部类:Outer.Inner in = new Outer().new Inner();
      在外部其他类中访问内部类:Outer.Inner in = new Outer().new Inner();

3.当内部类在成员位置上,就可以被成员修饰符修饰
3.1当内部类被static修饰后,就只能访问外部类中的static成员,出现访问局限
  class Outer {
   private int x = 1;
   static class Inner {
    public void seeOuter() {
          System.out.println(x); //error
    }
   }
  }
3.2在外部其他类中,如何访问static内部类的非静态成员呢?
  new Outer.Inner().seeOuter();
  理由:因为外部内一旦被加载,静态内部类也被加载了,所以直接创建内部类对象调用方法即可
class Outer {
   private static int x = 1;
   static class Inner {
    public void seeOuter() {
    System.out.println(x);
    }
   }
  }
  public class Test{
   public static void main(String[] args){
    new Outer.Inner().seeOuter();
   }
  }
3.3在外部其他类中,如何访问static内部类的静态成员呢?
    Outer.Inner.seeOuter();
class Outer {
   private static int x = 1;
   static class Inner {
    public static void seeOuter() {
    System.out.println(x);
    }
   }
  }
  public class Test{
   public static void main(String[] args){
    new Outer.Inner().seeOuter();
   }
  }
3.4.当内部类中定义了静态成员,该内部类必须是静态的
  class Outer {
   private static int x = 1;
   class Inner {
    static int y = 2; //error
    public static void seeOuter() { //error
     System.out.println(x);
    }
   }
  }  
3.5.当内部类中的静态方法访问内部类时,内部类也必须是静态的(参考上面2中B位置1处)

4.方法内部类(局部内部类)
  把类放在方法内
  class Outer {
         public void doSomething(){
             class Inner{
                  public void seeOuter(){  
                  }
              }   
         }
  }
4.1、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化
4.2、方法内部类对象不能访问该内部类所在方法的非final局部变量  
     class Outer {
     int b = 1;
         public void doSomething(){
              final int a =10;
              class Inner{
                   public void seeOuter(){
                       System.out.println(a);// a 必须是final类型
     System.out.println(b);// b 可以不是final类型的
                  }
              }  
              Inner in = new Inner();
              in.seeOuter();   //只能在方法内部访问内部类
         }
         public static void main(String[] args) {
              Outer out = new Outer();
              out.doSomething();
         }
     }
4.3、方法内部类的修饰符
     与成员内部类不同,方法内部类更像一个局部变量
     可以用于修饰方法内部类的只有final和abstract
4.4、静态方法内的方法内部类
     静态方法是没有this引用的,因此在静态方法内的内部类遭受同样的待遇,即:只能访问外部类的静态成员
5.匿名内部类
    匿名内部类就是内部类的简写格式
    定义匿名内部类的前提:内部类必须继承一个类或实现接口
    匿名内部类就是一个匿名子类对象
  格式:new 父类或者接口(){定义子类的内容}
回复 使用道具 举报
感觉楼上已经回复的很全面了。
回复 使用道具 举报
rel4x 中级黑马 2014-9-22 20:38:11
8#
学习了。。。
回复 使用道具 举报
本帖最后由 caixingke 于 2014-9-24 23:31 编辑

我来讲一点, 纯粹我个人的理解, 关于内部类的一些本质的内部, 纯干货, 但不把各种情况全部罗列出来的.
(仅罗列各种情况但不说明原因, 这样死记硬背也记不住的. 要记得住, 就得事物的本质)
希望能帮助到大家.
如果有讲得不对的, 或者不好的地方, 请指正. 谢谢.
(我是C/C++程序员出身, 所以理解一些东西时总是喜欢用指针的角度去理解.
Java的语法看似没有用到指针, 但其语言理论仍然需要用指针的, 比如引用, 本质仍然是指针)

对于非静态内部类, 其对象的空间中, 保留了一个指向外部类对象的指针.----这个很重要哦!
即, 意味着, 要创建非静态的内部类, 必须要有外部类对象先!
但是, 仅仅从外部类对象的空间, 是无法知道是否用这个外部类对象创建过其内部类对象,
因为外部类的存储空间中没有相关的数据域指向对应的内部类对象的空间.
所以, 在外部类中, 我们不能直接访问内部类的成员;
而, 在内部类中, 我们却可以直接访问外部类的成员.
局部内部类(匿名内部类其实也是局部内部类的一种) 中, 我们可以直接访问其所在方法的局部变量.
----至于, 为什么这个局部变量要求是final我就不知道了.
但我知道, JDK1.8的新特性是, 其不要求这个局部变量必须是final的.-----JDK1.8的新特性!

对于 静态内部类. 由于它是静态的, 所以其不依赖于外部类对象.
注意, 静态内部类也是可以有非静态成员的, 因此对静态内部类进行实例化也是有意义的,
但这个实例化不依赖于外部类对象(因为静态内部类是外部类的静态成员).
即, 在静态内部类的对象的存储空间中, 没有指向外部类对象的域.----很重要哦!
所以, 在静态内部类中, 不能直接访问外部类的非静态成员, 而只能访问外部类的静态成员.
而外部类 能访问静态内部类的静态成员, 但是不能直接访问静态内部类的非静态成员.
回复 使用道具 举报
内部类与外部类之间的成员互相访问
内部类可以访问外部类的任何成员,包括private成员。
外部类访问内部类的成员需要创建内部类的对象,之后可以访问内部类的任何成员,包括private成员,需要注意的是成员内部类不可以有静态成员。
当外部类的成员和内部类的成员重名时单单用this是区分不了的。在内部类中访问外部类的成员时可以用如下语法区分
<外部类类名>.this.<外部类中需要被访问的成员名>;
回复 使用道具 举报
cherry@cookie 来自手机 中级黑马 2014-9-26 08:07:26
11#
这么多,看看都不容易
回复 使用道具 举报
还未解决吗
回复 使用道具 举报
不知道楼主想问什么
回复 使用道具 举报
内部类又称为嵌套类,可以把内部类理解为外部类的一个普通成员。

内部类访问外部类
里面的可以自由访问外面的,规则和static一样。(访问非静态时必须先创建对象)

具体如下:

非静态内部类的非静态方法
直接访问

[java] view plaincopy
public class Outter {  
    int i = 5;  
    static String string = "Hello";  
      
    class Inner1{  
        void Test1 (){  
            System.out.println(i);  
            System.out.println(string);  
        }  
    }  
}<span style="font-family:Arial,Helvetica,sans-serif"> </span>  
静态内部类的非静态方法
因为静态方法访问非静态外部成员需先创建实例,所以访问i时必须先new外部类。

[java] view plaincopy
public class Outter {  
    int i = 5;  
    static String string = "Hello";  
      
    static class Inner2{  
        void Test1 (){  
            System.out.println(new Outter().i);  
            System.out.println(string);  
        }  
    }  
}  
静态内部类的静态方法
规则如上

[java] view plaincopy
public class Outter {  
    int i = 5;  
    static String string = "Hello";  
      
    static class Inner2{  
        static void Test2 (){  
            System.out.println(new Outter().i);  
            System.out.println(string);  
        }  
    }  
}<span style="font-family:Arial,Helvetica,sans-serif"> </span>  
外部类访问内部类
大方向:因为将内部类理解为外部类的一个普通成员,所以外面的访问里面的需先new一个对象。

非静态方法访问非静态内部类的成员:
new 内部类对象

[java] view plaincopy
public class Outter {  
    void Test1(){  
        System.out.println(new Inner1().i);  
    }  
    class Inner1{  
        int i = 5;  
//      static String string = "Hello";  定义错误!  
    }  
}  
静态方法访问非静态内部类的成员
静态方法Test2访问非静态Inner1需先new外部类;

继续访问非静态成员i需先new 内部类

所以访问规则为:new Outter().new Inner1().i。

[java] view plaincopy
public class Outter {  
    static void Test2(){  
        System.out.println(new Outter().new Inner1().i);  
    }  
    class Inner1{  
        int i = 5;  
//      static String string = "Hello";  定义错误!  
    }  
}<span style="font-family:Arial,Helvetica,sans-serif"> </span>  
非静态方法访问静态内部类的成员
先“外部类.内部类”访问至内部类。

若访问静态成员,则需先new再访问;若访问非静态成员,则可直接访问。

[java] view plaincopy
public class Outter {  
    void Test1(){  
        Outter.Inner2 inner2 = new Outter.Inner2();  
        System.out.println(inner2.i);  
        System.out.println(inner2.string);  
        System.out.println(Outter.Inner2.string);  
    }  
    static class Inner2{  
        int i = 5;  
        static String string = "Hello";   
    }  
}<span style="font-family:Arial,Helvetica,sans-serif"> </span>  
非静态方法访问非静态内部类的成员
先“外部类.内部类”访问至内部类,再new即可访问静态成员。

[java] view plaincopy
public class Outter {  
    void Test1(){  
        Outter.Inner1 inner2 = new Outter.Inner1();  
        System.out.println(inner2.i);  
    }  
    class Inner1{  
        int i = 5;  
//      static String string = "Hello"; 定义错误!  
    }  
}  

匿名内部类
匿名内部类访问外部成员变量时,成员变量前应加final关键字。

[java] view plaincopy
final int k = 6;  
((Button)findViewById(R.id.button2)).setOnClickListener(new OnClickListener() {  
    @Override  
    public void onClick(View v) {  
        // TODO Auto-generated method stub  
        System.out.println(k);  
    }  
});  
回复 使用道具 举报
dsh 中级黑马 2014-10-1 08:22:23
15#
静态内部类只可以访问外部类中的静态成员变量与成员方法  而非静 态的内部类即可以访问静态的也可以访问非静态的外部类成员方法与成员变量     访问时记住一点,访问时你要看你访问的东西在内存中是否已经出现,
回复 使用道具 举报
本帖最后由 hacker◊紫猫 于 2014-10-2 22:33 编辑

内部类访问外部类直接调用即可,外部类调用内部类许需要在内部类所在外部类中建立方法在方法中建立内部类对象
在方法中调用内部类。在测试函数中格式为   外部类.内部类  a=new外部类().new内部类();
回复 使用道具 举报
内部类的访问规则: 1,内部类可以直接访问外部类中的成员,包括私有。        之所以可以直接访问外部类中的成员,是内部类中持有了一个外部类的引用。格式:外部类名.this 2,外部类要访问该内部类,必须建立内部类对象;   访问格式: 1,当内部类定义在外部类的成员变量位置上,而且费私有,可以再外部其他类中直接建立内部类对象。 格式:外部类名.内部类名 变量名 = 外部类对象.内部类对象; Outer.Inner in = new Outer().new Inner();   2,当内部类在成员位置上,就可以被成员修饰符所修饰。 比如,private:将内部类在外部类中进行封装。        static:内部类就具备了静态的特性。        党内部类被static修饰后,只能直接访问外部类中的static成员,出现了访问局限。          在外部其他类中,如何访问static内部类的非静态成员呢?        new Outer.Inner().function();          在外部其他类中,如何访问static内部类的静态成员呢?        outer.Inner().function();   注意:当内部类中定义了静态成员,该内部类必须是静态的。          当外部类中的静态为方法访问内部类时,内部类也必须是静态的。 */ class Outer {        private static int x= 3;        static class Inner //静态内部类        {               static void function()               {                      System.out.println("innter:"+x);               }        } } class InnerClass1 {        public static void main (String[] args)        {               Outer.Inner.function();               new Outer.Inner().function();//直接访问内部类中的成员。 //            Outer.Inner in = new Outer().new Inner(); //            Inner.function();        } }

评分

参与人数 1黑马币 +13 收起 理由
tercell + 13 赞一个!

查看全部评分

回复 使用道具 举报
嗯,很有用
回复 使用道具 举报
zhangshoutuo 发表于 2014-9-20 17:09
1.内部类可以直接访问外部类中的成员,包括私有
      原因:因为在内部类中持有一个外部类的应用,格式: ...

瞬间明了,多谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马