4

何らかの理由で、定義されているパッケージの外部で抽象クラスを実装できないようです。package1 の抽象クラスは、package2 のクラスに実装できません。なぜこれは合法的な Java ではないのですか?

package com.stackoverflow.abstraction.package1;

abstract public class BaseClass {
    abstract Long foo();
}

package com.stackoverflow.abstraction.package1;

public class Implement1 extends BaseClass {
    @Override
    Long foo() {
        return null;
    }
}


package com.stackoverflow.abstraction.package2;

import com.stackoverflow.abstraction.package1.BaseClass;

/** Compiling this class will output
* - Implement2 is not abstract and does not override abstract method foo() in BaseClass
* - error: method does not override or implement a method from a supertype
*/

public class Implement2 extends BaseClass {
    @Override
    Long foo() {
        return null;
    }
}

実行中: OS X 10.6.8 - Java(TM) SE ランタイム環境 (ビルド 1.6.0_31-b04-415-10M3646) - OpenJDK ランタイム環境 (ビルド 1.7.0-u4-b13-20120301) 両方の Java バージョンを試しました。もちろん、同時にではありません:)

4

3 に答える 3

14

そのメソッドはパッケージ レベルの可視性であるため、他のパッケージでオーバーライドすることはできません。

abstract Long foo();

メソッドに修飾子がない場合 (デフォルト、package-private とも呼ばれます)、そのメソッドは独自のパッケージ内でのみ表示されます。

本当にオーバーライドする必要がある場合は、protected代わりにそれを作成してください。

protected abstract Long foo();

情報

于 2012-05-29T12:31:44.390 に答える
7

2 つのfooメソッドには、デフォルトの「パッケージ」アクセス権があります。あなたのImplementation2クラスはメソッドを呼び出すことさえできなかったので、それをオーバーライドできることはあまり意味がありません。

どのレベルのアクセス権が必要かは明確ではありません、最も簡単な方法はおそらく両方を公開することです。現時点では、 の発信者のみpackage1が を呼び出すことができますBaseClass.foo()が、 の発信者のみがpackage2を呼び出すことができますImplement2.foo()。それは明らかにあまり意味がありません。誰がメソッドにアクセスできるようにしたいですか? クラスまたはサブクラス内の呼び出し元のみがそれを呼び出せるようにする場合は、作成します。protectedそれ以外の場合は作成しpublicます。

アクセス修飾子の詳細については、Java 言語仕様(およびJava チュートリアル)のセクション 6.6 を参照してください。特に、さまざまなアクセス修飾子を通過した後:

それ以外の場合は、型が宣言されているパッケージ内からアクセスが発生した場合にのみ許可されるデフォルト アクセスがあると言います。

于 2012-05-29T12:34:17.520 に答える
4

4 つのアクセス修飾子があります:
- public - どこでも使用できます
- private - クラス内でのみ使用できます
- protected - クラスおよびそれを継承するクラス内でのみ使用できます
- パッケージ アクセス (デフォルト、修飾子なし) - できますクラスが属するパッケージでのみ使用します

。この場合、モディフィケータはなく、一般にパッケージ アクセスのように扱われます。

于 2012-05-29T12:36:17.133 に答える