黑马程序员技术交流社区

标题: 关于建立匿名内部类的问题 [打印本页]

作者: 闪亮未来    时间: 2013-11-5 11:17
标题: 关于建立匿名内部类的问题
本帖最后由 闪亮未来 于 2013-11-5 14:18 编辑
  1. abstract class AbsDemo
  2. {
  3.         abstract void show();
  4. }

  5. class Outer
  6. {
  7.         int x=3;

  8.         public void function()
  9.         {
  10.                 AbsDemo d=new AbsDemo()
  11.                 {
  12.                         int x=5;
  13.                         void show()
  14.                         {
  15.                                 System.out.println("x="+x);
  16.                         }
  17.                         void abc()
  18.                         {
  19.                                 System.out.println("heihei");
  20.                         }
  21.                 };
  22.                 d.show();
  23.                 d.abc();
  24.         }
  25. }



  26. class InnerClassDemo4
  27. {
  28.         public static void main(String[] args)
  29.         {
  30.                 new Outer().function();
  31.         }
  32. }
复制代码
问题1:
这里面的匿名内部类中定义了x=5,而外部类中定义了x=3,为什么不会编译失败,因为记得之前好像说过内部类中不能引用局部变量啊,要引用的话必须用 final 修饰了才可以。

问题2:
这里最后那个 d.show();没问题,但是d.abc();编译失败,应该是父类中没有这种方法,可是我想问的是子类不是继承了父类中的方法吗,这建立的是子类的匿名方法啊,

又不是建立父类的,子类相当于新增的功能,子类有,为什么不行啊。

作者: ciowok    时间: 2013-11-5 11:51
父类里面加个
abstract void abc();
因为d对象属于AbsDemo类型,调用d.abc()它会去AbsDemo类里面找这个方法,显然是找不到.
public class Demo2 {
  public static void main(String[] args) {
    A a = new B();
    B b = new B();
    a.a();
//    a.b();//The method b() is undefined for the type A
  }
}
abstract class A{
  abstract void a();
}
class B extends A{
  void a(){
    System.out.println("B");
  }
  void b(){
    System.out.println("b");
  }
}
作者: zdrain    时间: 2013-11-5 12:02
首先恭喜你,你很有主见,这是一个爷们应该有的素质,但是很遗憾的告诉你,你的理解是错的

首先,外部类x = 3的问题,可能你没深入练习并且理解他的真正概念,外部类的x是成员变量,是随着对象加载存储在对内存中,你所理解的final修饰,其实是内部类在访问局部变量的时候,也就是public void function()里定义的变量,需要用到final修饰,这个需要你自己再去理解一下

关于第二个问题,毕老师在视频里说的再清楚不过了,父类引用指向子类对象,编译时看左边,这个再三强调的,父类的引用指向父类没有的方法你认为他会给你编译通过吗?好好再理解一遍吧。

要认真哦!
作者: 何超    时间: 2013-11-5 13:14
AbsDemo d=new AbsDemo(){方法体}

new AbsDemo(){方法体}相当于在内存中直接创建了一个匿名的子类对象
AbsDemo d 然后父类引用指向了这个子类对象
于是栈内存的d指向了堆内存的匿名子类对象地址

于是此时你的 d.show()  d.abc()  操作的地址都是 你名字类对象地址

于是你的show输出的就是匿名子类对象里面的 x=5

至于  d.abc()   毕老师的视频里不是说了  非static方法的时候是  编译看左  运行看右  么

你的父类里是没有abc()方法   所以编译应该无法通过


我是这样看的 = =  哪里不对还望指出 我好长知识···
作者: ~﹏~    时间: 2013-11-5 13:48
我在你的代码中回答你的问题把,这样会清楚一点:
  1. abstract class AbsDemo
  2. {
  3.         abstract void show();
  4. }
  5. class AbsDemoImpl extends AbsDemo
  6. {

  7.         int x=5;
  8.         @Override
  9.         void show() {
  10.                 // TODO Auto-generated method stub
  11.                  System.out.println("x="+x);
  12.         }
  13.         void abc()
  14.     {
  15.             System.out.println("heihei");
  16.     }
  17.        
  18. }
  19. class Outer
  20. {
  21.         int x=3;

  22.         public void function()
  23.         {
  24.                         /**
  25.                          * Test1
  26.                          */
  27.                 AbsDemo d=new AbsDemo()
  28.                 {
  29.                         //这里面的匿名内部类中定义了x=5,而外部类中定义了x=3,为什么不会编译失败?
  30.                         int x=5;//因为这个x和外面的x不是一个变量
  31.                         @Override
  32.                         void show()
  33.                         {
  34.                                 System.out.println("x="+x);//这里引用的x=5的那个x
  35.                         }
  36.                         public void abc()
  37.                         {
  38.                                 System.out.println("heihei");
  39.                         }
  40.                 };
  41.                 d.show();
  42.                 //d.abc();//因为这里的d类型是AbsDemo,但是在这个类中没有提供abc方法;
  43.                     /**
  44.                      * Test2
  45.                      */
  46.                    
  47.                 //这样是可以的,因为在AbsDemoImpl中有abc方法
  48.                 AbsDemoImpl d1=new AbsDemoImpl();
  49.                 d1.show();
  50.                 d1.abc();
  51.                
  52.                 /**
  53.                      * Test3
  54.                      */
  55.                 //这样是不行了,因为d2声明的是AbsDemo类型,尽管它指向AbsDemoImpl但是,java虚拟机还是找不到abc方法
  56.                 AbsDemo d2=new AbsDemoImpl();
  57.                 d2.show();
  58.                 //d2.abc();
  59.         }
  60. }


  61. public class t1 {

  62.         /**
  63.          * @param args
  64.          */
  65.         public static void main(String[] args) {
  66.                 // TODO Auto-generated method stub
  67.                 new Outer().function();
  68.         }

  69. }
复制代码





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