public class First {
public void methodOne() {
System.out.println("in Parent methodOne");
}
public void methodTwo() {
System.out.println("in Parent methodTwo");
}
}
public class Second extends First{
private void methodOne() {
System.out.println("methodOne");
}
@Override
public void methodTwo() {
System.out.println("methodTwo");
}
public static void main(String[] args) {
First first = new Second();
first.methodOne();
}
}
在第二课中,我们有一个私有方法“methodOne”。这在eclipse中显示错误为“无法降低从First继承的方法的可见性”。
我知道这个错误是因为覆盖方法不应该降低可见性
即使它显示编译错误,它也会执行正常并将输出显示为in Parent methodOne
。如果是编译错误,为什么要生成输出?
当我将访问说明符更改为protected时,它会在控制台中提供预期的编译错误!
答案 0 :(得分:2)
如果您查看课程Second
使用decompiler
,methodOne
将如下所示
private void methodOne()
{
throw new Error("Unresolved compilation problem: \n\tCannot reduce the visibility of the inherited method from First\n");
}
由于Reference是父类,并且方法可见,因此调用父方法。
Eclipse编译器标识methodOne
是父级的重写方法,应遵循重写方法规则。
答案 1 :(得分:1)
是的,我可以在 Spring Tool Suite版本:3.7.0.RELEASE 中重新创建该问题。 虽然存在待处理错误,但在强制运行时虽然存在错误,但会发生父方法一输出中的。 Eclipse可能会忽略错误代码块,因为它被强制执行。
我执行了以下代码,
class First {
public void methodOne() {
System.out.println("in Parent methodOne");
}
public void methodTwo() {
System.out.println("in Parent methodTwo");
}
}
public class Second extends First{
// private void methodOne() {
// System.out.println("methodOne");
// }
@Override
public void methodTwo() {
System.out.println("methodTwo");
}
public static void main(String[] args) {
First first = new Second();
first.methodOne();
}
}
我在Parent methodOne 中得到作为输出。
在代码中,您将对象分配给其父级的引用。
First first = new Second();
由于班级Second
的方法不是methodOne
,因此调用methodOne
班级中的First
方法。
假设您将第二个methodOne
声明为Public
。
然后你会得到 methodOne 作为输出。
覆盖时,
请考虑以下示例。
class ABCD {
int x = 10;
static int y = 20;
public String getName() {
return "ABCD";
}
}
class MNOP extends ABCD {
int x = 30;
static int y = 40;
public String getName() {
return "MNOP";
}
}
public static void main(String[] args) {
System.out.println(new MNOP().x + ", " + new MNOP().y);
ABCD a = new MNOP();
System.out.println(a.x); // 10
System.out.println(a.y); // 20
System.out.println(a.getName()); // MNOP
}
希望这有帮助。
答案 2 :(得分:1)
我认为这就是"魔术"在Eclipse编译器中,无论如何它都会尝试编译它。
此示例运行正常,因为在运行时,永远不会调用错误的方法compileError
:
public class EclispeCompilerErrorExample {
public static void main(String[] args) {
if(false) {
compileError();
}
else {
System.out.println("But run anyways");
}
}
private static void compileError() {
int i = "this wont comppile";
}
}
private
的示例有效,因为您的方法永远不会被调用(它是一个私有方法,First
- 对象参考不可访问),因此调用First.methodOne
。当其protected
实际上是'#34;可达到'#34;代码,因此抛出异常。
答案 3 :(得分:-2)
如果你想覆盖子类中的方法,子类中指定方法修饰符的范围必须大于基类。 就像你的程序一样,方法methodOne的第二类修饰语必须是公开的。