问题:当我用匿名内部类调用变量 x 时,无论父类中是否有定义变量 x ,程序都能运行,而匿名内部类不也是用多态的引用创建的子类对象么?为什么会编译通过,希望高手能解答一下,感激不尽;
代码如下:
class Super
{
//当我注释掉这行代码时,用多态父类引用创建子类匿名对象还是能调用show方法,还是能输出子类的 x 变量值?
int x = 4;
//当我注释方法时,编译还是会失败,这说明匿名内部类还是具备多态的特性呀?为什么成员变量就不具备多态特性呢?
void show()
{
}
}
class Demo extends Super
{
static int x = 9;
public static void main(String[] args)
{
int x = 8;
Super s = new Super()
{
int x = 6;
void show()
{
System.out.println(x);
}
};
//下面函数的输出层级关系是:6(匿名子类对象中的变量)--4(父类中的变量)--8(主函数中的变量)--9(类中的静态变量)
s.show();
//当我注释掉父类中的成员变量 x 时,编译失败;而匿名内部类还是能正常运行;
towDemo();
}
public static void towDemo()
{
int x = 5;
//父类引用指向子类对象时,只能调用父类中的成员,不可以调用子类中特有的成员;
Super s1 = new Demo();
//输出的结果为父类中的变量 x = 4;
System.out.println(s1.x);
}
}
class Super
{
//当我注释掉这行代码时,用多态父类引用创建子类匿名对象还是能调用show方法,还是能输出子类的 x 变量值?
//楼主 这里还是一样,编译看的是左边,show方法调用时要访问 x 如果父类中没有 x 就会报错
int x = 4;
//当我注释方法时,编译还是会失败,这说明匿名内部类还是具备多态的特性呀?为什么成员变量就不具备多态特性呢?
//注释点此方法 编译失败,是因为,下面你重写此方法的原因造成的, 关于这句没有看懂你想说什么意思 为什么成员变量就不具备多态特性呢?
void show()
{
}
}
class heima extends Super
{
static int x = 9;
public static void main(String[] args)
{
int x = 8;
Super s = new Super()
{
int x = 6;
void show()
{
System.out.println(x);
}
};
//下面函数的输出层级关系是:6(匿名子类对象中的变量)--4(父类中的变量)--8(主函数中的变量)--9(类中的静态变量)
s.show();
//------------------------------------------------------------------------
//这个地方是 编译看左边,也就是父类,如果父类没有show方法报错, 运行看右边 执行原则是就近原则 所以是6
//-----------------------------------------------------------------------------
//当我注释掉父类中的成员变量 x 时,编译失败;而匿名内部类还是能正常运行;
towDemo();
}
public static void towDemo()
{
int x = 5;
//父类引用指向子类对象时,只能调用父类中的成员,不可以调用子类中特有的成员;
Super s1 = new heima();
//输出的结果为父类中的变量 x = 4;
//------------------------------------------
//这个地方你注意,当时成员变量时,编译看左边,运行也是看左边,所以他访问的是父类的成员变量
//-----------------------------------
System.out.println(s1.x);
}
}作者: 无知的xiaopihai 时间: 2014-10-16 16:47
楼主的问题也是蛮不错的,还在解决中。。。。。作者: 会飞的蜗牛 时间: 2014-10-19 16:57
看楼主问题:你纳闷的是什么Super类中没有了x的定义这个也能运行!
void show()
{
System.out.println(x);
}
但是你打印输出的只是个变量!你在匿名内部类中重写了x,你如果去掉这句重写int x = 6;然后父类中仍然没有变量x的话肯定报错。如果你父类中没有定义变量x,你就相当于重新在这个匿名内部类中定义了个x,肯定程序没问题啊。
最后一句:去掉父类中的x定义后,你可以在 s.show();后面再加一句,System.out.println(s.x);肯定报错啊!因为你不只是打印x,你是引用它,父类中必须有定义才可以。作者: 祁连山下的哨兵 时间: 2014-10-19 19:40
楼主你好,你把两个概念弄混了,用你父类引用s来调用子类中的show()方法,然后输出子类的成员变量,肯定是这样,子类被创建对象之后(匿名对象),成员变量已经被封装到了对象里。成员都具有多态性,变量和方法,如果你用父类引用s直接调用一下父类成员变量:s.x 那么输出的肯定是父类中的4:下面举个小例子来看一下:
class TestDemo
{
public static void main(String[] args)
{
//System.out.println("Hello World!");
Person p=new Student();
p.show();//输出的肯定是子类中被封装在对象中的成员变量
System.out.println("age="+p.age);//输出的肯定是父类中的成员变量
}
}
class Person
{
int age=6;
void show()
{}
}
class Student extends Person
{
int age=10;
void show()
{
System.out.println("age="+age);
}
}作者: 祁连山下的哨兵 时间: 2014-10-19 19:47
System.out.println("age="+this.age);前面省略了this,this,代表本类对象,p就是本类对象new Student()的引用,而age成员属性封装在对象中作者: SenGoo 时间: 2014-10-21 16:25
匿名内部类和多态不是一回事吧!作者: xiaochongbojue 时间: 2014-10-21 17:11
您好,当你在匿名内部类中同样定义了x变量的时候,就产生了变量的隐藏。并且在你的匿名匿名内部类中覆盖了父类的show方法,那么 s对象调用的是本类中定义的x 变量。所以此时父类中有没有成员变量x 是无关紧要的。另外你可以测试一下,在父类的show方法中加上输出x的语句,子类,或是匿名内部类中声明x变量,且子类不覆盖父类void方法,那么输出的将是父类的x 的值作者: Jeik 时间: 2014-11-2 14:17
首先多态是运行期不是编译期间的概念。
Super s = new Super()
{
int x = 6;
void show()
{
System.out.println(x);
}
};
你这里的代码相当于又创建了一个匿名的super类。通过变量s指向这个super类。
解答疑问一:
当你把原始的super类中,成员变量x注释掉 当然会报编译错误呀。就好比一个模板,它上面没有x.你要通过这个模板来创建一个新的模板,新的模板肯定是和原来一样的呀。原来的都没有,新的肯定也没有呀。
解答疑问二:你注释super()里的方法之所以会报编译失败同上理;