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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘晓康 中级黑马   /  2012-4-4 21:40  /  1745 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

//如果类a继承类b,实现接口c,而类b和接口c中定义了同名变量
interface InterfaceDemo
{
    int a=10;
}
class FuDemo
{
        static int a=20;
}
class Demo123 extends FuDemo implements InterfaceDemo
{
        static int a=210;

        public static void main(String[] args)
        {
                //System.out.println("a的值为:"+a);  
                //提示:对a的引用不明确,FuDemo中的变量a与InterfaceDemo中的变量a都匹配

        //System.out.println("a的值为:"+super.a);
        //困惑一:为什么不能调用父类中变量a?
                //是不是因为super不能调用父类中的静态成员

        System.out.println("a的值为:"+a);//困惑二:此处是否省略this.a呢?

        System.out.println("a的值为:"+FuDemo.a);

             System.out.println("a的值为:"+InterfaceDemo.a);
        }
}
准备解决别人发的问题的,结果把自己给饶进去了,但是感觉不错,收获了很多。

6 个回复

倒序浏览
this不能出现在static修饰的函数中,所以System.out.println("a的值为:"+a);//困惑二:此处是否省略this.a呢?不是省略this,只能用类名调用。
super也一样不能出现在static修饰的函数中。同理,System.out.println("a的值为:"+FuDemo.a); 也只能用类名调用。
因为 static修饰的函数属于类,也就是说其调用者是类
static 修饰的属性存在于共享空间。所以你一运行测试类就立刻加载了父类,接口和子类中各自的 a  属性。
接口中定义的常量本来就是 public static final 默认修饰的。
回复 使用道具 举报
当然, 你可以new 出对象来调用它们的 a  属性。因为类方法和类属性可以用对象来调用, 但是不建议这样使用。
正因为static 修饰的属性存在于共享空间, 所以
FuDemo f= new FuDemo();
System.out.println(f.a);//------------20.
FuDemo ff= new Demo123();
System.out.println(ff.a);//----------20.说明此处不是打印子类中的 a 属性。
回复 使用道具 举报
首先,在第一句的问题上在本类中有同名变量的话,是优先走本类的,
而且主函数是静态方法,是不能出现非静态的引用 例如 this ,super
回复 使用道具 举报
本帖最后由 孙利川 于 2012-4-4 23:12 编辑

this、super都不能用静态方法中,因为静态方法随着类的加载而加载。
而this、super指向的却是具体对象。
当程序运行时,类会先加载到内存,静态方法遂即加载到内存,而此时并没有建立对象。
所以在静态方法中引用this、super都会报错。
困惑一处的代码会报错。
困惑二处的代码是不能加this的。
回复 使用道具 举报
接口的变量是常量,不会变了。第一个提示当然是指示不明,不用说;困惑一是不能使用静态的。困惑二是有提示是一样的,指代不明。既然有多个a,在访问是必须指明 的。
回复 使用道具 举报
System.out.println("a的值为:"+a);
原理就是:静态方法中只能调用静态成员。还记得老毕视频前几章里,把函数与主函数定义在一个类中,这些函数前面都要加上static么?当时说让你我们死记,现在知道这个原因了。

而下面的两行代码,其实就是类名直接调用静态成员,没什什么好多说的。

记结果没什么意义的,要知道一个类加载进来,都做了些什么事。

当你编译成功后,会在相应路径下生成class文件,而这些class文件就是我们所说的中间码文件,字节码文件或者java可运行文件。
jvm就会去读取这些文件,当然要有一个入口,就是main函数,之所以是静态的,因为他要随着类的加载而加载,而它又是特殊的,因为只有它才会被jvm调用。入口类加载的同时,自身的静态成员也会被加载。如果这个继承某类,实现某接口,那么这些类或接口中的静态成员也会被加载进来。
所有的静态成员放在方法区中的静态区中。

当你在Demo123中复写了变量a后,这个a就专属于 Demo123这个类。而如果你不复写,对于Demo123这个类而言,有两个变量a,而且都是合理的,编译可以通过,但是运行过程中只要你调用a就会报错。

类一加载,这些静态就已经存在了。此时还没有对象的产生。也可以说,你上面的那段代码直到执行完都没产生过一个对象。所以不可能存在this和super。

顺便多说一句,你所有的this和super其实都用在某个非静态方法里,当这个非静态方法在方法区内产生的同时,在这个方法的内部会产生两个变量this和super。

上面的这些都在毕老的视频里,说的很清楚的。

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马