2012-01-27 78 views
6

方法继承方法的知名度,我得到这个编译器错误:不能减少从父

You cannot reduce the visibility of a inherited method.

我有以下代码

class Parent {  
    public void func() { 
     System.out.println("in Parent"); 
    } 
} 

public class TestClass extends Parent {  
    public static void main(String args[]) { 
     parent obj=new TestClass(); 
     obj.addTest(); 
    } 

    private void func() { 
     System.out.println("in child");   
    } 
} 

这里父类有func()方法,它是公开的,由覆盖子类TestClass这是私人的。现在编译器会抛出错误,我不能降低可见性。从技术上讲,每当我创建TestClass指定给父类型对象的对象时,由于func()方法被覆盖,所以TestClass的func()将始终被调用,那么为什么我们应该关注可见性?这个错误背后的原因是什么?有人能解释清楚吗?

回答

20

这是因为子类具有的void func()方法private知名度,但超有知名度public

如果你的代码被允许编译,它会在运行时发生爆炸,如果你这样做:

parent p = new TestClass(); 
p.func(); // boom - func is public in parent, but TestClass's impl is private, so no access would be allowed 

“修理” 这一点,让子类的func方法public

public class TestClass extends parent { 
    ... 
    public void func() { // give it public visibility 
     System.out.println("in child");   
    } 
} 


请使用标准的命名约定;在这种情况下“类应该开始一个大写字母” - 即Parentparent

+0

谢谢Bohemain。我明白了理由。感谢您指出命名标准。 – Mojoy 2012-01-27 19:16:43

+0

嗨..这让我想到为什么我不能在超类中公开的方法在子类中保护修饰符?由于受保护的修饰符可以在任何包的包和子类中访问! – Mojoy 2012-01-28 13:40:47

+0

受保护的方法对其他任意类都不可见,但super的'public'方法是,所以同样的推理适用。 *任何*可见度降低都是错误的。 – Bohemian 2012-01-28 19:21:14

11

section 8.4.8.3 of the Java Language specification

The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, or a compile-time error occurs. In more detail:

  • If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
  • If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise, a compile-time error occurs.
  • If the overridden or hidden method has default (package) access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs.

Note that a private method cannot be hidden or overridden in the technical sense of those terms. This means that a subclass can declare a method with the same signature as a private method in one of its superclasses, and there is no requirement that the return type or throws clause of such a method bear any relationship to those of the private method in the superclass.

毕竟,你只想到一个private方法被程序代码中调用同一个班级 - 如果因为重写公共方法而最终被调用,那会很混乱。

2

如果你仔细想想,不能够做到这一点是有道理的..

的原因是,你可以通过子对象四周,好像是父一(即你可以使用父类型一个TestClass实例的引用类型)。

例如

parent p = new TestClass(); 

有可能一些代码的其他地方,它使用parent类型,并调用该方法:

例如

public static void aMethod(parent aParent){ 
    p.func(); 
} 

如果能够减少方法然后调用aMethod(p)的知名度将不得不放弃某种运行时异常的 - 不允许这样可以保证这不是必需的。