0

抽象クラスがあるとしましょう:

abstract class DBTable {

    abstract boolean append();

}

また、DBTable から継承する子クラスもあります。

// Client objects are rows of a database table
class Client extends DBTable {

    @Override
    boolean append() {

    }
}

最後に、Client オブジェクトの非正規化形式を表すために使用した Client のサブクラスがあるとします (これで問題ないと思います。すべて同じパッケージにあり、Client.Expand -is a- Client です)。

私がやりたいのは、Client.Expand の append() メソッドをオーバーライドし、Client の append() メソッドまで連鎖させてから、サブクラスにのみ適した作業に戻ることです。このようなもの...

    // Expand is a member class of Client
    static class Expand extends Client {

        @Override
        boolean append() {
            super.append();
            :
            :
        }
    }

Javaはこれを許可しますか? 親クラスで既にオーバーライドされているメソッドをオーバーライドしようとすると、IDE からエラーが発生します。オーバーライドされたメソッドをオーバーライドして、子クラスに必要な追加の実装を提供できるようにする必要があるようですが、Java はこの種の継承用に構築されていないのでしょうか?

4

2 に答える 2

0

あなたの例にはいくつかの問題があります:

  1. クラスのメンバーを静的として宣言すると、このメンバーはクラスに関連付けられます。そのクラスのインスタンスでは使用できません。たとえば、Expand の append メソッドにsuper .append() などのコードがある場合、「super」は「class」ではなくインスタンスを指します。したがって、静的定義と矛盾します。コメントで示唆されているように、クラス宣言から static を削除する必要があります。

  2. 子クラスは、内部クラスであってはなりません。これは、許可されていたとしても、適切な設計ではありません。意味的に考えると、サブクラスはスーパークラスのメンバーではないからです(この場合、親子の言葉は誤解を招く可能性があり、スーパークラスとサブクラスの方が優れています)。スーパークラスは、それを拡張する可能性のあるクラスについて認識してはならず、自己完結型である必要があります。したがって、サブクラスを別のクラスに移動することをお勧めします。

  3. あなたのデザインには他にもいくつかの問題があります。まず第一に、ネーミングは主題を説明していません。client が行を表す場合、Row、または TableRow、... の方が適切な名前であり、ExpendedRow は次のクラスの名前です。

しかし、もっと重要なことに、テーブルを拡張する行は良い考えではありません。より良いアプローチは、Row クラスと Table クラスで Row を構成することです。このようなもの:

// Client objects are rows of a database table
class Row {

    @Override
    boolean append() {

    }
}

class Expanded extends Row{

        @Override
        boolean append() {
            super.append();
            :
            :
        }
    }
class DBTable {

    Row row;

}
于 2013-05-31T15:39:06.290 に答える
0

問題が見つかりました。恥ずかしいです。私自身の防御の一環として、私自身の質問に少し遠回しに答えます。

クラスがテーマに従属するようにクラスを設計するのが好きです。そのテーマに関連するすべての機能を、同じクラスに配置するのが好きです。クラスの構造は他のデータベース モデル クラスでも繰り返されることが多いため、これは特にデータベース データ モデル クラスに適しています。

正確にはどういう意味ですか?

さて、これが私の Client クラスの「構造」です。ご覧のとおり、いくつかのメンバー クラスが含まれています。

+----------------------------+
|  CLIENT                    |
+---+------------------------+
    |  static EXPAND         |
    +------------------------+
    |  static GHOST          |
    +------------------------+
    |  static BUILDER        |
    +------------------------+
    |  static INQUISITOR     |
    +------------------------+
    |  static QUERYBUILDER   |
    +------------------------+
    |  static JDBCFactory    |
    +------------------------+

私はこのデザインがとても好きです。これは、Client オブジェクトを構築するクラスを Client クラスと同じファイルに置くことができ、セミニーモニックの "new Client.Builder()" で呼び出すか、SQL クエリを構築するオブジェクトを作成できることを意味します。 「new Client.QueryBuilder()」を使用した Client オブジェクトの場合。オブジェクトが JDBC 結果セットから Client オブジェクトを作成するためのファクトリになるクラスは、「new Client.JDBCFactory」などでインスタンス化できます。これはとても気に入っています。

マイナス面は…ブレースが多いことです。

そして...注意しないと、間違ったコンテキストで何かを入力する可能性があります。この場合、EXPAND メンバー クラスに入れたいと思っていた append() メソッドの定義を入力していた場所は、実際にはブレースのすぐ外側にあり、CLIENT のコンテキストに入力していました。

Client には既に append() メソッドがあったため、IDE は私が既に append() メソッドを持っている同じクラスのメソッドをオーバーライドしようとしていると不平を言っていました。

はい、Java はオーバーライド チェーンを完全にサポートしています。私のIDEやJVMには何の問題もありません...私だけです。@Robe やその他の方々のご意見に改めて感謝いたします。

于 2013-05-31T22:15:04.963 に答える