案例1:
我有一个Interface Inter.java:
interface Inter
{
void abcd();
}
基类:
class Base
{
void abcd()
{
System.out.println("Base abcd");
}
}
派生类:
class Use extends Base implements Inter
{
void abcd() //intentionally not using public
{
System.out.println("Use abcd");
}
public static void main(String[] args)
{
Use u = new Use();
u.abcd();
}
}
现在我编译它:
gyan@#ns:~/Desktop$ javac Inter.java Base.java Use.java
Use.java:3: error: abcd() in Use cannot implement abcd() in Inter
void abcd()
^
attempting to assign weaker access privileges; was public
1 error
gyan@#ns:~/Desktop$
这意味着类Use中的重写方法abcd()来自已实现的接口“Inter”,而不是来自基类“Base”。
案例2:
我们有一个包含以下代码的文件Test.java:
interface Ab
{
void run();
}
class A extends Thread implements Ab
{
public void run()
{
System.out.println("class A");
}
public static void main(String[] args)
{
A a = new A();
Thread t = new Thread(a);
t.start();
System.out.println("main method");
}
}
当我们执行它时,我们得到了:
gyan@#ns:~/Desktop$ java A
main method
class A
gyan@#ns:~/Desktop$
由于t.start()执行了方法run(),这意味着类的Thread的run()被覆盖了。但是在这种情况下,接口“Inter”的方法abcd()被覆盖了。
在案例1中:在类Use中覆盖了谁的方法abcd()? Class Base或接口Inter?错误说我们正在覆盖接口Inter的abcd()。但在案例2中:似乎我们没有覆盖接口Ab的方法运行。因为我们可以通过调用t.start()来执行run()方法。只有在我们覆盖Thread类的run()时才有可能。
答案 0 :(得分:1)
您的类中的方法会覆盖基类方法并同时实现接口。
覆盖方法与实现接口并不完全相同:
方法的实现和覆盖总是可以扩展其可见性,但不能减少它。这意味着:
接口中的方法始终是公共的,即使接口中未指定“public”修饰符也是如此。因此,他们的实现也必须是public =>这就是你在案件中得到的错误1
作为旁注,在你的情况2中,你使用错误的线程。不要子类Thread。相反,创建一个实现Runnable或Callable接口的类,并将其提交给线程池(请参阅java.util.concurrent中的类,或者使用java 8的ForkJoinPool.commonPool().submit(myTask)
进行快速测试。
答案 1 :(得分:0)
两者。方法覆盖取决于方法的名称和签名,而不是它的定义位置。如果在多个祖先上定义,它将覆盖两者。 注意:如果在一个中定义为public,在另一个中定义,则它将变为公共。
答案 2 :(得分:0)
在Inter
接口中,void abcd();
是抽象方法的定义。所有抽象方法本质上都是公开的。
界面中的所有抽象,默认和静态方法都是隐式公共的,因此您可以省略public修饰符。
所以,虽然Inter
说abcd()
是public
,但Use
中的实际实施却表示abcd()
的实施是package-private
},这是一个较弱的访问权限。这应该符合您的评论"//intentionally not using public"
传统上,abcd()
也应该使用注释@Override
(尽管这不是一项严格的要求)。
在第二个示例中,Thread
类提供了run()
的具体实现。鉴于A#run()
是公共的,您已满足接口Ab
对访问说明符所强加的要求。然后,A#run()
继续覆盖Thread#run()
- 这正是我们期望继承行为的方式。
总而言之,我们刚刚看到了extends
(扩展或重写类方法)和implements
之间的区别(给定类为接口中的所有方法状态提供实现的契约)。 {This answer}对此有更深入的了解,并且是一本很好的读物。
让我知道这个答案的任何部分是否需要更清晰。