7

私はとのパッケージを持っています

public abstract class Player { /*...*/ }

そしてこれら

public abstract class GamePlayer extends Player { /*...*/ }
public abstract class TournamentPlayer extends Player { /*...*/ }
public abstract class StatelessPlayer extends Player { /*...*/ }

パッケージのユーザーには Player が必要ですが、パッケージを壊さずに使用するには、 Player を直接拡張しないようにする必要があります。代わりに、提供されているサブクラスの 1 つを拡張する必要があります。

質問: ユーザーが Player を直接拡張できないようにするにはどうすればよいですか?

この禁止が意図されていることを明らかにする方法を探しています。

4

5 に答える 5

20

のコンストラクターPlayerがパッケージアクセスのみを持つようにします。そうすると、コンストラクターを呼び出したり、コンストラクターを自分で拡張したりすることができなくなります。に明示的なコンストラクターがまだない場合は作成Playerします(そうでない場合、コンパイラーはデフォルトのパブリックパラメーターなしコンストラクターを作成します)。

(これをコンストラクターに行うことを提案しただけであることに注意してください。クライアントが引き続き使用できるように、クラス自体をパブリックにすることができます。)

これが機能するのは、(内以外のjava.lang.Object)コンストラクターがスーパークラスコンストラクターを(明示的または暗黙的に)呼び出す必要があるためです。アクセス可能なコンストラクターがない場合、サブクラスを作成することはできません。

于 2009-04-08T13:23:37.233 に答える
9

Playerのコンストラクターが公開されていないことを確認してください。

public abstract class Player {
    Player() {
        // initialization goes here
    }
}

次に、クラスは同じパッケージ内からPlayerを拡張できますが、パッケージの外部から拡張することはできません。

于 2009-04-08T13:24:28.603 に答える
0

ええと...Playerクラスを非公開にしますか?「public」を省略すると、package-privateになります。つまり、同じパッケージ内のクラスのみがそれを拡張できます。

ただし、人々が自分のクラスをそのパッケージに入れることを完全に妨げるものは何もありません。署名されたJARに入れることでそれを防ぐことができると思います。そうすると、同じパッケージに署名されていない(または異なる署名の)クラスをロードしようとしても失敗します。

于 2009-04-08T13:25:35.340 に答える
0

お勧めします

  • クライアントにアクセスさせたいものの、作成またはサブクラス化はしないもののパブリック インターフェイスを作成する
  • クライアントがアクセスして作成またはサブクラス化するものに対してパブリック クラスを作成する
  • それ以外は非公開にする必要があります

このアプローチの問題点は、すべてを 1 つのパッケージに収める必要があることです。これは、ライブラリが大きくなるにつれて、組織化に悪影響を及ぼします。

保護された複数のパッケージを使用できるようにするには、OSGi を見てください。

OSGi を使用すると、バンドル (jar) が他のバンドルにアクセスできるパッケージを制限したり、追加の可視性を許可する「フレンド」バンドルを設定することさえできます。

Java の保護ユニットとしてのパッケージ モデルは、大きくなるライブラリを本当に保護したい場合には十分ではありません...

于 2009-04-08T15:06:02.883 に答える
-1

「パッケージプライベート」アクセスとも呼ばれるデフォルトのアクセス修飾子を使用します。つまり、アクセス修飾子を指定しないでください

abstract class Player { /*...*/ }

SunのWebサイトにあるここのドキュメントでは、すべてのアクセス修飾子について詳しく説明しています。

于 2009-04-08T13:23:08.997 に答える