タグ付けされた質問 「inheritance」

継承は、プログラミング言語のサポートに応じて、既存のオブジェクトのコードを再利用したり、既存のオブジェクトからサブタイプを確立したりする方法です。

5
インターフェースと継承:両方の長所?
私はインターフェースを「発見」し、それらを愛するようになりました。インターフェイスの優れた点は、それがコントラクトであることであり、そのコントラクトを満たすオブジェクトは、そのインターフェイスが必要な場所であればどこでも使用できます。 インターフェースの問題は、それがデフォルトの実装を持つことができないことです。これは、ありふれたプロパティの苦痛であり、DRYを無効にします。これは、実装とシステムの分離を維持するため、これも良い方法です。一方、継承はより緊密な結合を維持し、カプセル化を壊す可能性があります。 ケース1(プライベートメンバーによる継承、適切なカプセル化、密結合) class Employee { int money_earned; string name; public: void do_work(){money_earned++;}; string get_name(return name;); }; class Nurse : public Employee: { public: void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/); }; void HireNurse(Nurse *n) { nurse->do_work(); ) ケース2(単なるインターフェース) class IEmployee { virtual …

9
チェスの駒の継承と構成
このstackexchangeを簡単に検索すると、一般的に構成は継承よりも柔軟であると一般に考えられていますが、常にプロジェクトなどに依存し、継承の方が適している場合があります。3Dチェスゲームを作りたいのですが、各ピースにはメッシュがあり、場合によっては異なるアニメーションなどがあります。この具体的な例では、両方のアプローチのケースが間違っていると主張できるように思われますか? 継承は次のようになります(適切なコンストラクターなどを使用) class BasePiece { virtual Squares GetValidMoveSquares() = 0; Mesh* mesh; // Other fields } class Pawn : public BasePiece { Squares GetValidMoveSquares() override; } これは確かに「is-a」の原則に従いますが、構成は次のようになります。 class MovementComponent { virtual Squares GetValidMoveSquares() = 0; } class PawnMovementComponent { Squares GetValidMoveSquares() override; } enum class Type { PAWN, BISHOP, //etc …

2
dynamic_castの使用を回避するための適切な設計?
いくつかの調査を行った後、私が頻繁に遭遇する問題を解決する簡単な例を見つけることができないようです。 Squares、Circles、およびその他の形状を作成し、画面に表示し、それらを選択した後でそれらのプロパティを変更して、すべての周囲を計算できる小さなアプリケーションを作成したいとします。 私はこのようなモデルクラスを行います: class AbstractShape { public : typedef enum{ SQUARE = 0, CIRCLE, } SHAPE_TYPE; AbstractShape(SHAPE_TYPE type):m_type(type){} virtual ~AbstractShape(); virtual float computePerimeter() const = 0; SHAPE_TYPE getType() const{return m_type;} protected : const SHAPE_TYPE m_type; }; class Square : public AbstractShape { public: Square():AbstractShape(SQUARE){} ~Square(); void setWidth(float w){m_width = w;} …

1
PHPでクラスを実装するためのメソッドシグネチャの変更
PHPのGenericsの欠如に対して、静的コード検査で型の一貫性を検出できる適切な回避策はありますか? サブクラスを作成する抽象クラスがあり、メソッドの1つが1つの型のパラメーターの取得から、そのパラメーターのサブクラスであるパラメーターの取得に変更されるように強制します。 abstract class AbstractProcessor { abstract function processItem(Item $item); } class WoodProcessor extends AbstractProcessor { function processItem(WoodItem $item){} } これは、許可されていないメソッドシグネチャを変更するため、PHPでは許可されていません。Javaスタイルのジェネリックスを使用すると、次のようなことができます。 abstract class AbstractProcessor<T> { abstract function processItem(T $item); } class WoodProcessor extends AbstractProcessor<WoodItem> { function processItem(WoodItem $item); } しかし、PHPはこれらをサポートしていません。 この問題のためのグーグル、人々はinstanceof実行時にエラーをチェックするために使用することをお勧めします例えば class WoodProcessor extends AbstractProcessor { function processItem(Item $item){ if …

5
一般化よりも構成を優先することをどうやって知ることが常に正しい選択でしょうか?
オブジェクトが物理的に存在するかどうかに関係なく、さまざまな方法でモデリングすることができます。多くの場合、一般化または合成を任意に使用できます。ただし、「一般化よりも構成を優先する」というGoFの原則により、構成を使用するようにガイドされます。したがって、たとえばラインをモデル化する場合、Point(一般化)を拡張する代わりに、タイプPoint(構成)の2つのメンバーPointAおよびPointBを含むクラスを作成します。これは、オブジェクトが通常ははるかに複雑であるにもかかわらず、モデル化するための構成または継承を任意に選択できる方法の単純化された例にすぎません。 これが正しい選択であることをどのように知ることができますか?少なくとも、それが間違っている場合に実行すべき大量のリファクタリングが存在する可能性があるため、問題になりますか?

7
単一の日付と日付範囲の両方を表すことができるプロパティ:適切にモデル化する方法は?
私は2つの方法で「送料見積もり」を表すことができるシステムで働いています。 特定の日付:アイテムはその日付で出荷されることが保証されています 日間隔:アイテムは今日から「X to Y」日で発送されます モデルに関する情報は、意味的には同じで、「発送予定」です。配送見積もりの​​情報をシステムから取得すると、見積もりが最初の形式か2番目の形式かがわかります。 このための現在のモデルは次のようになります。 class EstimattedShippingDateDetails { DateTime? EstimattedShippingDate {get; set;} Range? EstimattedShippingDayRange {get; set;} } Range 整数の「始まり->終わり」をラップする単純なクラスです。 struct Range { int Start {get; set} int End {get; set} public override ToString() { return String.Format("{0} - {1}", Start, End); } } 推定モデルのプロパティの1つだけが入力されるため、このアプローチは好きではありません。一方のプロパティでnullをテストし、もう一方のプロパティにデータがあると仮定する必要があります。 各プロパティは、ユーザーには異なる方法で表示されますが、現在のスイッチングロジックが存在するカスタムMVC DisplayTemplateを使用して、UIの同じ場所に表示されます。 @Model EstimattedShippingDateDetails @if …

6
クラスでJavaストリームをフィルタリングする場合、instanceofの代わりはありますか?
1つのクラスを拡張するすべての型がJavaコレクションにパックされるプロジェクトで、予期しない状況が発生しました。ただし、そのクラスの特定の拡張のみに追加のメソッドが含まれています。それを「also()」と呼びましょう。他の拡張機能にはないことをはっきりさせておきます。そのコレクション内のすべてのアイテムで1つのタスクを実行する直前に、それを実装するすべてのアイテムでalso()を呼び出す必要があります。 最も簡単な方法はこれです: stuff.stream().filter(item -> item instanceof SpecificItem) .forEach(item -> ((SpecificItem)item).also())); stuff.stream().forEach(item -> item.method()); それは正常に動作しますが、「instanceof」がそこにあるのは快適ではありません。これは通常、コードの悪臭のマーカーです。このクラスを取り除くためだけにこのクラスをリファクタリングする可能性は非常に高いです。しかし、劇的なことをする前に、コミュニティに問い合わせて、StreamsまたはCollectionsのどちらかについてより経験のある人がより簡単な解決策を持っているかどうかを確認したいと思いました。 例(確かに非排他的)として、クラスによってエントリをフィルタリングするコレクションのビューを取得することは可能ですか?

4
OOD:Java継承とキャストによる子メソッドへのアクセス
私はいくつかのクラス持っているParentとしChild1... Child9Javaで実装されています。Parent抽象クラスであり、子クラスのすべての共通変数(多くのParent場合、インターフェースではなく抽象クラスを作成した主な理由です)、いくつかの抽象メソッド、およびいくつかの実装されたメソッドを含みます。 一部の子クラスには、それらに固有のカスタムメソッドがあります。ダウンキャストを使用して子メソッドを呼び出すことがよくあります。 Parent p = new Child1(); ((Child1) p).child1SpecificMethod(); どういうわけか、これはOODの悪い習慣だと感じていますが、それが本当にデザインの改善方法であるかどうかはよくわかりません。 -編集- とにかく変更する必要があるのは、多くの(今のところ)共通変数を整理するためにParentクラスを使用し、それらを具象クラスのメンバー(またはコンテナーオブジェクト)にすることです。

4
ささいな保護されたゲッターは過剰に露骨ですか?
私が以前に本当に考えたことがないもの(AS3構文): private var m_obj:Object; protected function get obj():Object { return m_obj; } private var m_str:String; protected function get str():String { return m_str; } 少なくともサブクラスはm_objまたはm_strを設定できません(ただし、m_objを変更することはできます)。 私の質問:これは単なる露骨なやりすぎですか? このプログラマーの質問: 単純にパブリックプロパティにするのではなく、クラスプロパティのゲッター/セッターをいつまたはなぜ使用する必要があるのでしょうか。 重複として提案されています。 その質問は、パブリックプロパティとプライベートプロパティのみを扱い、プロパティをゲッターとセッターでラップする必要があるかどうかという点で異なります。私の質問では、保護された変数と、継承するクラスがそれらの変数とどのように相互作用するかに焦点を当てています。 したがって、代替実装は次のようになります。 protected var m_obj:Object; //more accessible than a private variable with a protected getter protected var m_str:String; //more accessible than a …

1
JavaScriptオブジェクトとCrockfordのThe Good Parts
最近、JSでOOPを実行する方法についてかなり考えています。特に、カプセル化と継承に関してはそうです。 Crockfordによれば、classicalはnew()により有害であり、prototypeとclassicの両方が制限されています。これらのコンストラクターの使用は、カプセル化にクロージャーを使用できないことを意味します。 最近、私はカプセル化について次の2つの点を検討しました。 カプセル化するとパフォーマンスが低下します。各オブジェクトのメソッドには異なるクロージャーがあるため(各オブジェクトには異なるプライベートメンバーがあるため)、プロトタイプではなく各メンバーオブジェクトに関数を追加できます。 カプセル化によって、醜い「var that = this」の回避策が強制され、プライベートヘルパー関数が接続されているインスタンスにアクセスできるようになります。それか、毎回privateFunction.apply(this)でそれらを呼び出すようにしてください。 私が言及した2つの問題のいずれかの回避策はありますか?そうでない場合でも、カプセル化はそれだけの価値があると考えていますか? 補足:Crockfordが説明する機能パターンでは、new()とconstructor.prototypeの使用を完全に忘れているため、パブリックメンバーにのみ触れるパブリックメソッドを追加することもできません。古典的な継承とnew()を使用するだけでなく、Super.apply(this、arguments)を呼び出してプライベートメンバーと特権付きメソッドを初期化するハイブリッドアプローチは優れていますか?

6
継承を使用してコードを再利用する場合、再利用の利点を飲み込むのが難しいと思いませんか?
私は約8年間コーディングを行ってきましたが、継承は柔軟性が高すぎるため、作成したコードと完全に混同されることがあります。最も簡単な例は次のとおりです。 abstract class AClass { protected void method1() { if(check()) { do1(); } else { do2(); } } protected abstract void do1(); protected abstract void do2(); } クラスの目的は、do1()とdo2()を実装してさらにロジックを実行できるようにすることですが、method1()をオーバーロードすることを決定すると、状況はすぐに複雑になります。 私は戦略パターンでのみコードを見つけます。コードは継承を通じてよく再利用されます。ほとんどの場合、基本クラスの設計者はそのサブクラスを非常によく知っており、その継承は完全にオプションです。 IoHandlerの4つのクラスによって継承されるクラスがあり、サーバーサイド、クライアントサイド、エッジサーバー、オリジンサーバーのサブクラスであり、私を狂わせ始めています。私はいつもコードのリファクタリングをしていました。うまくいくと思うアイデアを思いついたのですが、うまくいかなかったのです。人間の脳は一度に7つの情報しか保持できないと言われています。

1
Rails-STIを使用するかどうか…それが問題です
6か月前に、アプリのデータのモデル化について質問し、STIに向けてアドバイスを求めました(詳細については、Railsデータモデル-ベストプラクティスの質問を参照してください)。 私はそれをいじって、それをいくらか動かして、それから気を散らして、プロジェクトを休止状態にしました。 プログラミング/ RORの6か月の経験を活かして、ゼロから再び開発を始めたところ、ビールレシピの材料をモデリングする際に、再びこの壁にぶつかりました。 簡単に要約すると、3つの成分タイプ(麦芽、ホップ、および酵母)があるとします。それぞれがいくつかの属性(名前、価格、ベンダー)を共有しますが、それぞれにその成分タイプに固有の属性もあります。それらはすべて関連しています(それらはすべて成分です)が、「動作」は異なります(たとえば、穀物がすりつぶされ、ホップ/酵母などに適用されないものに対処するロジックが存在するなど)。 成分が十分に異なるので、dbに3つの別個のテーブルを置くことだけを考えています...しかし、コントローラーについてはどうですか?単一の成分コントローラーを使用して個別のモデルを管理できますか? 私はSTIの代替(クラステーブルの継承、およびマルチテーブルの継承)について読みましたが、すべてのソリューションは扱いにくいようです。STIの便利さ(タイプに関係なく、単一のテーブルクエリですべての成分を取得するなど)の欠点がない(nullフィールド、サブクラスやフィールドを追加し続けると扱いにくいテーブルなど)代替手段はありますか? 申し訳ありませんが、この質問は少しあいまいですが、明確な解決策を見つけることができないように感じ、現在、どちらの方法がより悪が少ないかを理解しようとしています。他の人もこれに対処していると思います。さまざまなソリューションの長所と短所を聞きたいです。ありがとう!

5
メソッドを呼び出すとき、base.methodnameとthis.methodnameを使用する必要がありますか?
C#では、継承されたクラスセットを使用して、メソッドを呼び出すときに、オーバーライドされたメソッドであるかどうかに関係なく、キーワード 'base.methodname and this.methodname' ...を使用する必要がありますか? コードはロジックの点で変更される可能性が高く、おそらくIF-ELSEのような条件が後日発生する可能性があります。したがって、その時点で、開発者はコードの各行を再訪して、どのメソッドが呼び出されるかを正しく選択するように強いられます--- base.methodname()またはthis.methodname()ELSE。 NETフレームワークはDEFAULT(そのbase.methodname()だと思います)を呼び出し、ロジック全体がトスに進むことができます。
8 c#  inheritance 

2
ダウンキャストとアップキャストという用語は誰が決めたのですか?
私の知る限り、この用語は継承階層が伝統的にどのように表示されるかから来ており、下部に拡張型、上部に親型があります。 これは、次のleftcastingおよびrightcastingを呼び出す気がしない限り、少し無意味です。 用語がそのままである理由を私は探していませんが、コメントとして大歓迎です。私は最初にアップキャスティングとダウンキャスティングを紹介した人、そしてなぜ彼らがその名前を決めたのかについての参考文献を探しています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.