Java 如何在main中重写实例变量/方法?

Java 如何在main中重写实例变量/方法?,java,inheritance,Java,Inheritance,我想访问超类中的实例变量x。 我找不到它的语法。这可能吗 public class SuperBoss { int x = 10; } public class Boss extends SuperBoss { int x = 2; public static void main ( String[] args ) { Boss b = new Boss(); System.out.println(b.x); //prints out 2, I want it

我想访问超类中的实例变量
x
。 我找不到它的语法。这可能吗

public class SuperBoss {
    int x = 10;
}

public class Boss extends SuperBoss {
    int x = 2;

public static void main ( String[] args ) {
    Boss b = new Boss();
    System.out.println(b.x); //prints out 2, I want it to print out 10 
}

我一直试图使用关键字“super”,但没有成功。

它打印出
2
,因为您在
Boss
中声明
int x=2
x
的声明隐藏在
SuperBoss

通常,您会使用
super
关键字显式访问超类的
public
字段,但是这在主方法的
静态
上下文中不起作用。您可以定义一个小的辅助函数,该函数将获得超类的
x

public class Boss extends SuperBoss {
    int x = 2;

    public int getSuperX() {
        return super.x;
    }

    public static void main ( String[] args ) {
       Boss b = new Boss();
       System.out.println(b.getSuperX()); //prints out 2, I want it to print out 10 
    }
}
据我所知(我可能应该在JLS中查找详细信息),使用
super
访问隐藏的非私有字段是合法的,但只能从实例方法中访问。所以你可以这样做:

public class Boss extends SuperBoss {

    int x = 2;

    int getSuperX() {
        return super.x;
    }

    public static void main (String[] args) {
        Boss b = new Boss();
        System.out.println(b.getSuperX());
    }

}
Boss
类中添加
getSuperX()
方法:

public class Boss extends SuperBoss {

    int x = 2;

    public int getSuperX() {
        return super.x;
    }

    public static void main(String[] args) {
        Boss b = new Boss();
        System.out.println(b.getSuperX());
    }
}

发生的情况是,
Boss
的实例变量正在
SuperBoss
中隐藏同名的实例变量。您可以将实例临时强制转换为超类型类:

public static void main ( String[] args ) {
    Boss boss = new Boss();
    SuperBoss superBoss = boss;
    System.out.println(boss.x); //prints 2
    System.out.println(superBoss.x); //prints 10 
}

不建议这样做。出于封装的原因,您的实例变量不应该是可见的,即应该是私有的/受保护的。并且可能不应与父类中的变量具有相同的名称。

若要执行所需操作,需要在超类中将
x
声明为
受保护的
,而不要尝试在子类中重写它:

public class SuperBoss {
    protected int x = 10;
}

public class Boss extends SuperBoss {
    // int x = 2;

    public static void main ( String[] args ) {
        Boss b = new Boss();
        System.out.println(b.x);
    }
}
然而,实际上,几乎不需要
受保护的
数据。它可能导致的问题几乎与
公共
数据一样多。更好的是:

public class SuperBoss {
    private int x = 10;

    protected int getX() {
        return x;
    }
}

public class Boss extends SuperBoss {
    // int x = 2;

    public static void main ( String[] args ) {
        Boss b = new Boss();
        System.out.println(b.getX());
    }
}

是的,有办法。字段具有编译时绑定。你需要的是一个超级老板的角色:

public class SuperBoss {
    int x = 10;
}

public class Boss extends SuperBoss {
    int x = 2;

    public static void main ( String[] args ) {
        Boss b = new Boss();
        System.out.println(((SuperBoss)b).x);
    }
}

相关:可能:System.out.println(((SuperBoss)b.x)@zgnilec检查和测试comments@zgnilec伙计,这是最简单、最棒的答案哈哈。@LuiggiMendoza抱歉,我发布了一个解决方案,但忘了单击提交:|我正要使用
public int getSuperX()发布一个类似的解决方案
method with the same method content=P。现在又有一个人做了。谢谢你建议我们使用get方法,Hunter。@Luigimendoza它太恶心了,我不推荐它。你不推荐它,但把它作为答案发布,不要说它在任何地方都不推荐。此外,这只会导致糟糕的设计,它可以用来显示在现实世界的应用程序中不能做的事情。@LuiggiMendoza这不是代码审查。有些时候,像这样的恶作剧会产生这样的问题。主要的问题仍然存在:糟糕的设计。@LuiggiMendoza然而,这确实展示了java的一些功能,人们应该知道如何根据声明的实例类型访问内容。我希望zgnilec能够发表他的评论作为答案,因为他首先推荐了这个解决方案,但既然你有完全相同的解决方案,我就接受了这个。。哈哈,谢谢。@KacyRaye如果我们按时间去的话,我比他们两个都早到了。@Sotirios Delimanolis你的答案不正确,它显示了如何使用超类的对象而不是子类的对象访问超类字段。@tcb你知道如何使用调试器吗?获取我发布的代码,并在
println()
处使用断点运行它,然后查看对象的类型。将实例分配给另一个类型不会更改实例,它会更改其接口(强制转换)。我们正在做完全相同的事情,除了你在一行中做,我在两行中做。@KacyRaye最后的评论:你读了所有的答案,保留了最坏的答案。