使用受保护的访问修饰符覆盖没有访问修饰符的方法

7
当你重写方法时,不允许减少继承方法的可见性。根据下表,protectedno modifier更可访问:
            | 类    | 包     | 子类       | 外部
————————————+———————+—————————+——————————+———————
public      |  y    |    y    |    y     |   y
————————————+———————+—————————+——————————+———————
protected   |  y    |    y    |    y     |   n
————————————+———————+—————————+——————————+———————
no modifier |  y    |    y    |    n     |   n
————————————+———————+—————————+——————————+———————
private     |  y    |    n    |    n     |   n
y: 可访问 n: 不可访问
但是当我尝试覆盖f()(请参见SubClass)时,我会收到以下错误信息: Cannot reduce the visibility of the inherited method from MyInterface. MyInterface中的方法没有访问修饰符,而SubClass中的方法具有受保护的修饰符,因此更容易访问。 我在这里错过了什么?
public interface MyInterface {
  void f();
}

public abstract class MyClass {
  protected abstract void f();
}

public class SubClass extends MyClass implements MyInterface{
   protected void f() { }
}

5
你不应该override接口方法,而是应该实现(implement)它们。 - T.J. Crowder
1
@T.J.Crowder - jls jargon - 如果类C中声明的实例方法mC 覆盖 了超级接口中声明的另一个方法mI,则... - ZhongYu
@bayou.io:有趣,我从未听过这样的说法。 - T.J. Crowder
6个回答

13

接口中的方法隐式地具有public访问修饰符。因此,当您使用protected实现它时,它是一个较弱的访问修饰符。


@T.J.Crowder 这有点吹毛求疵,因为在实现时仍然使用 @Override - ajb
@Amila 这只适用于接口吗?还是还有其他情况下没有修饰符等于public的情况? - Stanko
1
据我所知,@Dongo 只能在接口中使用。 - Amila
@ajb:你知道吗?哦,嘿,看起来从Java 1.6开始(也就是几年前),你可以这样做:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5008260 - T.J. Crowder
1
@Amila:我是在提问而不是针对你的回答,只是为了澄清。(事实上,在你添加第二句话之前,我就已经写下了这条评论。)没有任何批评意图。 :-) - T.J. Crowder

3
在接口中的方法默认是public而不是default

2
来自Java doc
覆盖或隐藏方法的访问修饰符(§6.6)必须提供至少与被覆盖或隐藏方法相同的访问级别,如下所示:
1. 如果被覆盖或隐藏方法是public,则覆盖或隐藏方法必须为public;否则会出现编译时错误。
2. 如果被覆盖或隐藏方法是protected,则覆盖或隐藏方法必须为protected或public;否则会出现编译时错误。
3. 如果被覆盖或隐藏方法具有默认(包)访问权限,则覆盖或隐藏方法不能为private;否则会出现编译时错误。
接口中的方法默认为public。因此,您无法使用除public以外的任何修饰符覆盖/隐藏此方法。

0
在Java中的接口中,所有的方法都是公共的。 所有的变量都是公共静态常量。(常数)

0
在Java的学习阶段,这是一个很好的问题。但你必须记住,有默认和隐式访问修饰符,比如在这种情况下接口默认是public 的。

public interface MyInterface {
  void f();
}

public interface MyInterface {
  public void f();
} 

两者在隐式上是相同的。接口被设计成以公开方式暴露其行为。


0

接口方法天生就带有public

给予

protected void f(); 

或者

private void f();

在MyInterface中看看你得到了什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接