黑马程序员技术交流社区

标题: 内部类问题 [打印本页]

作者: 兜兜转转    时间: 2013-8-27 10:47
标题: 内部类问题
本帖最后由 潘才新 于 2013-9-2 21:53 编辑
  1. public class InnerTestDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 MyOuter.myMethod();
  6.         }

  7. }

  8. class MyOuter
  9. {


  10.            class MyInner
  11.                         {
  12.                                 int a =23;
  13.                                      public  void show()
  14.                                      {
  15.                                               System.out.println(a);

  16.                                      }
  17.                         }

  18.         public static void myMethod()
  19.         {
  20.          //不能编译
  21.                 //new MyInner().show();
  22.                 //编译成功,为什么呢?老师说上面这种方法不能编译,可是下面这个能编译
  23.                 MyOuter.MyInner  in = new MyOuter().new MyInner();
  24.                 in.show();
  25.         }
  26.         
  27. }
复制代码
老师说外层类的静态方法不能使用new MyInner().show();的方法去访问内部类,但是MyOuter.MyInner in = new MyOuter().new MyInner();
in.show();为什么可以呢?老师好像没讲这种方式呢,却别在哪里?

作者: 黄文伯    时间: 2013-8-27 10:50
亲,如问题已解决请将分类的“未解决”改为“已解决”。
以后的问题贴也要及时更改分类哦~
作者: 兜兜转转    时间: 2013-8-27 11:07
彻底被内部类的访问规则搞糊涂了
作者: 范龙波    时间: 2013-8-27 11:41
先回答你第一个问题:
                // 不能编译
                // new MyInner().show();
new MyInner().show();你调用的地方搞错了,静态方法调用 非静态成员内部类. 这么写是有问题的.
因为这个方法优先于MyInner.class加载
第二个问题以下代码可以加载
MyOuter.MyInner in = new MyOuter().new MyInner();    主要还是加载到内存的顺序问题
作者: 兜兜转转    时间: 2013-8-27 11:53
范龙波 发表于 2013-8-27 11:41
先回答你第一个问题:
                // 不能编译
                // new MyInner().show();

public class InnerTestDemo
{
        public static void main(String[] args)
        {
                MyOuter.myMethod();
        }
}
class MyOuter
{
           class MyInner
                        {
                                int a =23;
                                     public  void show()
                                     {
                                              System.out.println(a);
                                     }
                        }
        public static void myMethod()
        {
//不能编译
//new MyInner().show();
//编译成功。因为内部类相当于外层类的成员,因为myMethod()方法存//在时,这些非静态的成员必须建立对象才能在内存中存在,所以要先//创建外层内的对象,再创建内部类的对象。
                MyOuter.MyInner  in = new MyOuter().new MyInner();
                in.show();
        }
}



这是的后来的想法,不知道对不对


作者: 范龙波    时间: 2013-8-27 12:18
刚才我的答案误导了你,更正一下
先说字节码加载的顺序问题:当加载InnerTestDemo.class时与它相关的类MyOuter和MyInner都会被一起加载到内存
你在myMethod()中调用MyInner时因为它是内部类,它需要外部类引用,这时如果你用用javac编译它应该会提示"无法找到this"
作者: 兜兜转转    时间: 2013-8-27 12:38
范龙波 发表于 2013-8-27 12:18
刚才我的答案误导了你,更正一下
先说字节码加载的顺序问题:当加载InnerTestDemo.class时与它相关的类MyOute ...

或许你讲的是对的,但是还是迷迷糊糊的,哥们,可以详细说说吗?  跪求解析,,,你这个this找不到是怎么回事呢?我这里没有用到this 啊?我知道静态方法里面不能使用this,但是编译会报告找不到this这样的异常?

作者: 范龙波    时间: 2013-8-27 12:45
main()调用myMethod()
myMethod()调用内部类
main()调用了内部类,main()只是一个程序入口它不是谁的成员方法 ,它如果想要调用一个类的内部类是不是要需要先new MyOuter();
作者: 兜兜转转    时间: 2013-8-27 12:59
范龙波 发表于 2013-8-27 12:45
main()调用myMethod()
myMethod()调用内部类
main()调用了内部类,main()只是一个程序入口它不是谁的成员方 ...

可是这里不是new 了,但是编译失败呀


作者: 潘才新    时间: 2013-8-27 13:19
大神无处不在,顶一个!
作者: 王广亚    时间: 2013-8-27 15:22
本帖最后由 王广亚 于 2013-8-27 15:26 编辑

可到你的问题和我刚回答的问题如出一辙,所以索性就把那个答案拷贝过来,看看是否能帮到你。
创建内部类对象:外部类名称.内部类名称 a=new 外部类().new 内部类();这是内部类非静态时创建方法。
                                                               外部类名称.内部类名称 a=new 外部类.内部类();这是内部类为静态时创建方法。下面是修改后的代码。

第一:在主函数中建立的对象,根据静态只能访问静态,所以在主函数中建立非静态内部类对象时要像在外部其他类中建立内部类对象一样建立。方法如上。
         如果你这样new MyInner().show();在主函数建立外部类非静态对象,你可以把内部类改为静态,如下:
  1. class Demo{
  2.         static class A{
  3.           private void print(){
  4.                   System.out.println("A、private()");
  5.           }
  6.         }
  7.         static class B extends A{
  8.           private void print(){
  9.            System.out.println("B、private()");
  10.           }
  11.         }
  12.         public static void main(String[] args){
  13.           B b = new B();
  14.           b.print();
  15.         }
  16. }
复制代码
要不就多定义一个非静态的外部类函数,在这个外部类函数中去访问建立内部类对象访问内部类这样这这个函数持有外部类的引用,所以他要访问内部类中的成员时是可以直接建立——new MyInner().show();
  1. class Demo
  2. {
  3. class A
  4. {
  5.   private void print()
  6.   {
  7.    System.out.println("A、private print()");
  8.   }
  9. }
  10. class B extends A
  11. {
  12.   private void print()
  13.   {
  14.    System.out.println("B、private print()");
  15.   }
  16. }
  17. public void ab()
  18. {
  19.   B b = new B();
  20.   b.print();
  21.   System.out.println("Demo、 void ab()") ;
  22. }
  23. public static  void main(String[] args)
  24. {
  25. Demo d=new Demo();
  26. d.ab;
  27.   //Demo d = new Demo();
  28. // d.ab();
  29. }
  30. }              
复制代码
下面只是改了一下在主函数中建立对象的那句代码。
  1. class Demo{
  2.         class A{
  3.           private void print(){
  4.                   System.out.println("A、private()");
  5.           }
  6.         }
  7.         class B extends A{
  8.           private void print(){
  9.            System.out.println("B、private()");
  10.           }
  11.         }
  12.         public static void main(String[] args){
  13.           Demo.B b = new Demo().new B();
  14.           b.print();
  15.         }
  16. }

复制代码

作者: 潘才新    时间: 2013-8-27 18:31
本帖最后由 潘才新 于 2013-8-27 18:32 编辑

如问题已解决请将分类的“未解决”改为“已解决”。如不懂。请参阅http://bbs.itheima.com/forum.php?mod=viewthread&tid=53426

作者: 肥猫    时间: 2013-8-27 20:36
这么理解吧,哥们,上面那种方式不能通过是因为一个内部类对象必须要依附一个外部类对象才行,而内部类的构造方法里有一个隐式的外部类对象上面那种方式NEW出来的内部类对象不依附外部类对象,所以会报错。
作者: 兜兜转转    时间: 2013-8-28 09:05
肥猫 发表于 2013-8-27 20:36
这么理解吧,哥们,上面那种方式不能通过是因为一个内部类对象必须要依附一个外部类对象才行,而内部类的构 ...

哥们,你的解释,我感觉找到点感觉了,不过,内部类持有对外部类的一个对象引用?你说的是Outer.this吗?然后你意思是说内部类有一个Outer.this引用,然后要实例化Inner 内部类的时候了,一定要实例化Outer吗?

作者: 辛春鹏    时间: 2013-8-31 10:23
在外部类的静态方法中创建外部类的对象,用外部类的对象创建内部类对象,调用内部类的方法。就可以了。也就是楼主的第二种方式。此时,myMethod虽然是静态方法,但是,在其内部有了对象,就可以调用了。关于你的第一种方式,改成     new MyOuter().new MyInner().show();就可以了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2