2011-12-20 12 views
2

これはかなり奇妙な質問です。誰かが私に最近尋ねたことは、これを達成するとは思えませんでした。継承中に特定の機能をキャンセルするにはどうすればよいですか?

Personは、いくつかのパブリック関数を持ち、帰属されるクラスとしましょう。属性の1つが目の色であり、2つの機能:getColor()setColor()があるとします。

TeacherPersonに拡張すると、そのプロパティが継承されます。

質問:getColor()setColor()以外の機能は継承したくない場合はどうすればよいですか?

私の初期の考えは、すべて@Overrideであり、何もしないで空を返すことでした。しかし、私はこれが安全な方法ではないと思います。もっと洗練された解決方法がありますか?

答えて

1

これは基本的にPersonの「契約」の定義であり、Personから継承することによって、教師はそのように行動することが「有望」である。

別にinterface PersonBaseinterface PersonWithEyes、たとえば、継承する人をリファクタリングから、あなたはちょっとあなたが発信者にPersonのまともな実装を提供したい場合は、その文脈で「正しいことを行う」と立ち往生しています。

+0

左フィールドですが有効な代替案:OOPモデルを削除し、代わりにエンティティモデルを使用します。 O :-) – BRFennPocock

+0

「有望」はここではいいキーワードです。私はそれを約束していることを知っている、私はこれを達成するための絶対に方法がないかどうかをチェックしていた。 –

+0

この場合、具体的には、 'COLOUR_UNKNOWN'の値を定義し、それをデフォルトにして、それを使って実行するかもしれません。 (ある時点で、未成年のビデオゲームプレイヤーを扱う米国のCOPPAの法律のために、私はそのようなことをいくつか行いました) – BRFennPocock

0

いいえ、意味がありません。

あなたは常にこの操作を行うことができることを考えてみましょう:

class Person { 
    public int getColor() { ... } 
    public void setColor(int x) { ... } 
} 

class Teacher extends Person {} 

... 

Person p = new Teacher(); // Create a Teacher 
p.setColor(5);    // But access it as if it were a Person 

それは「継承を防ぐ」ために何を意味するのでしょうか?

あなたはいつも、すなわち「持っている - 」の関係ではなく、「ある-」の関係

class Teacher { 
    private Person person = new Person(); 
} 

ような何かを行うことができます。しかしそれはあまり意味がありません。

1

親クラスに対して非公開にすることも、上書きすることもできます。それらをプライベートにすることはもちろん、親クラスの外でもそれらを無用にします。

もう一つの選択肢は、構成と委任を使用することです。それらのメソッドを渡すことはありませんが、きわめて細かいインターフェイスがない限り、is-a関係は失われます。

+0

はい、プライベートはオプションではありません。ありがとう! –

2

これは悪いことです。継承の全ポイントは、いくつかのインタフェース(またはあるクラスのサブクラス)のすべての実装が同じ契約を持っているということです。

新しいインターフェイスを定義する必要があります。メソッドを持たないクラスがスーパークラスになるように、デザイン全体を上下にずらすことも考えてください。

1

あなたが求めていることは、「道徳的な」意味では言えません。これを達成するために行うことは、あなたがすべきでないことです。どうして? のサブタイプはどこでも使用可能であると思われるので、スーパータイプはです。これはLiskov Substitution Principleと呼ばれます。

はそれについてこのように考える:あなたはPersonクラスを定義し、それがgetColor()setColor()方法を持っていることを指定する場合、基本的にあなたは、彼らがPerson参照を持っている場合、彼らは呼び出すことができることをユーザーのクラスのすべての約束を作っていますそれらの名前を持つメソッド。 Personをサブクラス化してTeacherクラスにすると、は同じ約束を継承します;誰かがあなたのTeacherオブジェクトのうちの1つをPerson参照で参照するかもしれないので、あなたはスーパークラスが作るすべての約束を尊重しなければなりません。

あなたが尋ねている間にCircle-ellipse Problemについて読むこともできます。それは、あなたが尋ねていることに密接に関連しています。

+0

円楕円問題はここでは関連していません... –

+0

非常にそうです。 Circle-Ellipseの問題でCircleにEllipseのサブタイプを作成しようとすると、EllipseがCircleに意味をなさない操作をサポートするという問題があります。これはTeacherをPersonのサブタイプにすることに匹敵し、PersonがTeacherにとって意味をなさない操作をしているという問題にぶつかります。 –

+1

しかし、「教師」には目があるので、基本クラスのプロパティは意味があります。これは 'Circle'対' Ellipse'の場合ではありません。 –

0

継承を使用しないでください。

階層を分割して、継承したいすべてのメソッドを持つ基本クラスを作成し、子孫に追加しないものを追加します。その優雅後

、Kierra騎士を名乗るひげと大きな脂肪のやつです...

オーバーライドと押すだけで、リファクタリングを言って、すべてのコードの上に大きなコメント、と、NotImplementedExceptionをスローします。

関連する問題