方法不会覆盖 Eclipse 中的包可见方法

Posted

技术标签:

【中文标题】方法不会覆盖 Eclipse 中的包可见方法【英文标题】:Method does not override package visible method in Eclipse 【发布时间】:2011-07-01 11:59:26 【问题描述】:

来自 Eclipse Java 编译器设置:方法不会覆盖包可见方法

“一个包默认方法在不同的包中不可见,因此不能被覆盖。启用此选项后,编译器会将这种情况作为错误或警告发出信号。”

如何触发此警告/错误?我正在寻找代码示例。

【问题讨论】:

【参考方案1】:

为什么此警告或错误很重要的一个示例请考虑以下示例:

package a;

public class Animal  

    // Note: no visibility modifier therefore package-private
    String makeNoise() 
        return "no noise defined";
    


package b;

import a.Animal;

public class Cat extends Animal 

    // Note: Eclipse will show the warning that it doesn't override
    public String makeNoise() 
        return "meow";
    



package b;

import a.Animal;

public class Dog extends Animal 

    // Note: Eclipse will show the warning that it doesn't override
    public String makeNoise() 
        return "bark";
    



package a;

import java.util.ArrayList;
import java.util.List;

import b.Cat;
import b.Dog;

public class Main 

    public static void main(String[] args) 
        // Make a list of Animals
        List<Animal> animals = new ArrayList<>();
        animals.add(new Cat());
        animals.add(new Dog());

        // Loop through the animals making their noises
        for (Animal animal : animals) 
            System.out.println(animal.makeNoise());
        
    


将整个内容复制粘贴到 Eclipse 中,它会整理类和包。然后运行Main 类。您可能希望它打印出来

meow
bark

但它会打印

no noise defined
no noise defined

这是一种令人困惑的行为,它意外地破坏了多态性。这样做的原因是Animal 子类CatDog 实际上根本没有覆盖makeNoise 方法,所以当makeNoiseAnimal 上被调用时,它使用Animal 实现。

要修复此代码,请将 publicprotected 修饰符添加到 Animal makeNoise 方法,然后重新运行代码,它现在将按预期工作。在这个简单的示例中,它非常清楚发生了什么,但在更复杂的情况下,这种行为可能会非常混乱并且可能不正确,因此应该认真对待警告。

【讨论】:

【参考方案2】:

Foo.java:

package foopackage;

public class Foo 
    String getString() 
        return "foo";
    

Bar.java:

package barpackage;

import foopackage.Foo;

public class Bar extends Foo 
    String getString() 
        return "bar";
    

应该这样做。

来自Eclipse Help docs:

一个包默认方法在不同的包中是不可见的,因此不能被覆盖。启用此选项后,编译器会将此类情况发出错误或警告信号。

【讨论】:

我写了一个等效的测试,它在@Override 行上给出了method does not override or implement a method from a supertype(至少对于Sun javac 1.6.0_22)。删除 @Override 注释会使示例编译。你的例子需要进口顺便说一句。 @sjr 不要把注释放进去,你会得到这个错误/警告。这也是一个很好的例子,说明为什么使用 @Override 注释是个好主意。 你测试过这个吗?你用的是什么javac版本?我没有得到这种行为:删除注释会导致示例编译。 @sjr:是的,我没有在 IDE 或其他任何东西中这样做。谢谢。 哦,是的,@Override 应始终在有效时使用。 :)【参考方案3】:
package a;

public class A 
    // package protected method foo : no visibility modifier
    void foo() 
    


package b;

public class B extends A 
    // although this method has the same signature as A.foo(), it doesn't 
    // override it because A.foo is not visible to B (other package)
    void foo() 
    

【讨论】:

【参考方案4】:
package b;

public class Foo 

    void test() 


package a;

import b.Foo;

public class Bar extends Foo 

    void test() 

【讨论】:

以上是关于方法不会覆盖 Eclipse 中的包可见方法的主要内容,如果未能解决你的问题,请参考以下文章

覆盖 touchesBegan:错误 - 方法不会覆盖超类中的任何方法

Eclipse插件,用于查找类/包中未使用的方法

Java 内部类可见性难题

supportedInterfaceOrientations 方法不会覆盖其超类中的任何方法

如何覆盖包命名空间中的不可见函数?

“方法不会覆盖其超类中的任何方法”Swift 3 [重复]