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

9
多重継承が嫌われる「本当の」理由はありますか?
私は常に、言語で複数の継承をサポートするというアイデアが好きでした。ほとんどの場合、意図的に無視されますが、想定される「置換」はインターフェースです。インターフェースは、多重継承が行うものと同じ基盤をすべてカバーするものではなく、この制限により、定型コードが増える場合があります。 私がこれまでに聞いた唯一の基本的な理由は、基本クラスのダイヤモンドの問題です。私はそれを受け入れることができません。私にとっては、「まあ、それを台無しにすることは可能だから、それは自動的に悪い考えだ」というようなひどい結果になります。ただし、プログラミング言語で何かを台無しにすることができます、と私は何を意味します。少なくとももっと徹底的な説明がなければ、私はこれを真剣に受け止めることはできません。 この問題を知っているだけで、戦いの90%になります。さらに、私は何年か前に「エンベロープ」アルゴリズムまたはそのようなものを含む汎用的な回避策について聞いたことがあると思います(これは鐘を鳴らしますか?)。 ダイヤモンドの問題に関して、私が考えることができる唯一の潜在的に本物の問題は、サードパーティのライブラリを使用しようとしており、そのライブラリ内の2つの一見無関係なクラスが共通の基本クラスを持っていることを見ることができない場合ですが、ドキュメンテーション、単純な言語機能では、たとえば、実際にコンパイルする前に、ダイヤモンドを作成する意図を明確に宣言する必要があります。このような機能を使用すると、ダイヤモンドの作成は意図的、無謀、またはこの落とし穴に気付かないためです。 すべてが言われているように...あらゆるあり、実際のほとんどの人は多重継承を憎む理由は、またはそれが良いよりも害の原因とヒステリーのすべてのちょうど束でありますか?ここにないものがありますか?ありがとうございました。 例 車はWheeledVehicleを拡張し、KIASpectraはCarとElectronicを拡張し、KIASpectraはラジオを含みます。KIASpectraにElectronicが含まれないのはなぜですか? それは電子だからです。継承と構成は、常にis-a関係とhas-a関係でなければなりません。 それは電子だからです。配線、回路基板、スイッチなどがあります。 それは電子だからです。冬にバッテリーが切れると、すべてのホイールが突然なくなったのと同じくらいのトラブルに見舞われます。 インターフェースを使用しないのはなぜですか?たとえば、#3を考えてみましょう。私はこれを何度も何度も書きたくないし、これを行うために奇妙なプロキシヘルパークラスを本当に作りたくない: private void runOrDont() { if (this.battery) { if (this.battery.working && this.switchedOn) { this.run(); return; } } this.dontRun(); } (その実装が良いか悪いかについては触れていません。)WheeledVehicleの何にも関連せず、Electronicに関連するこれらの機能のいくつかがどのように存在するか想像できます。 そこには解釈の余地があるので、その例に落ち着くかどうかはわかりませんでした。また、VehicleとFlyingObjectを拡張するPlaneや、AnimalとFlyingObjectを拡張するBirdの観点、またはより純粋な例の観点から考えることもできます。

1
ミックスインまたは特性は、単純な多重継承よりもどのように優れていますか?
C ++には単純な多重継承があり、多くの言語設計では危険なものとして禁止されています。しかし、RubyやPHPなどの一部の言語では、奇妙な構文を使用して同じことを行い、それをmixinまたはtraitsと呼びます。ミックスイン/特性は、単純な多重継承よりも悪用しにくいと何度も耳にしました。 それらを特に危険性の低いものにしているのは何ですか?ミックスイン/トレイトではできないが、C ++スタイルの多重継承では可能なことはありますか?彼らとダイヤモンドの問題に遭遇することは可能ですか? これは、多重継承を使用しているように見えますが、それらを使用できるように、それらがミックスイン/特性であるという言い訳をするだけです。

6
多重継承は単一責任原則に違反しますか?
2つの異なるクラスから継承するクラスがある場合、これはサブクラスが(少なくとも)2つのことを自動的に行うことを意味しないのですか?各スーパークラスから1つですか? 複数のインターフェイス継承がある場合、違いはないと思います。 編集:明確にするために、複数のクラスをサブクラス化するとSRPに違反する場合、複数の(マーカーまたは基本インターフェイス(Comparableなど))インターフェイスの実装もSRPに違反すると考えています。

2
ScalaのTraitsは「ダイヤモンドエラー」をどのように回避しますか?
(注:明白な理由のためにタイトルで「問題」の代わりに「エラー」を使用しました。;))。 ScalaでTraitsの基本的な読書をしました。これらはJavaまたはC#のインターフェイスに似ていますが、メソッドのデフォルト実装を許可します。 私は不思議に思っていました:これは「ダイヤモンドの問題」のケースを引き起こすことはできません。それが多くの言語がそもそも多重継承を避ける理由です。 その場合、Scalaはこれをどのように処理しますか?

5
Java(Android)での多重継承の適切な回避策
複数の継承を必要とするコードの適切な実装に概念的な問題がありますが、これは多くのオブジェクト指向言語では問題になりませんが、プロジェクトはAndroid用であるため、multipleのようなものはありませんextends。 私はそのような単純な異なる基底クラスから派生し、活動の束を持ってActivity、TabActivity、ListActivity、ExpandableListActivity、などまた、私は私がに配置する必要があり、いくつかのコードの断片を持っているonStart、onStop、onSaveInstanceState、onRestoreInstanceStateおよびすべての活動で他の標準のイベントハンドラ。 すべてのアクティビティの単一の基本クラスがある場合、特別な中間派生クラスにコードを配置し、それを拡張するすべてのアクティビティを作成します。残念ながら、複数の基本クラスがあるため、これは当てはまりません。しかし、コードの同じ部分をいくつかの中間クラスに配置することは、進むべき道ではありません。 別のアプローチは、ヘルパーオブジェクトを作成し、上記のイベントのすべての呼び出しをヘルパーに委任することです。ただし、これにはヘルパーオブジェクトを含める必要があり、すべてのハンドラーをすべての中間クラスで再定義する必要があります。したがって、ここでの最初のアプローチに大きな違いはありません-まだ多くのコードの重複。 Windowsで同様の状況が発生した場合、基本クラス(ActivityAndroid のクラスに「対応する」)をサブクラス化し、適切なメッセージを(1か所で)トラップします。 このためにJava / Androidで何ができますか?Javaインストルメンテーション(実際の例もあります)などの興味深いツールがあることは知っていますが、私はJavaの第一人者ではありません。 他の適切な解決策を見逃した場合は、それらに言及してください。 更新: Androidで同じ問題を解決することに興味がある人のために、簡単な回避策を見つけました。Applicationクラスが存在します。これは、とりわけインターフェイスActivityLifecycleCallbacksを提供します。すべてのアクティビティの重要なイベントをインターセプトし、重要なイベントに値を追加できるようにするために必要なことを正確に行います。このメソッドの唯一の欠点は、APIレベル14から使用できることです。多くの場合、これは十分ではありません(今日ではAPIレベル10のサポートが一般的な要件です)。

7
多重継承のユースケース
Javaは、言語をシンプルに保つという設計目標を回避するという理由で、多重継承を省略します。 Java(とそのエコシステム)は本当に「シンプル」なのだろうか。Pythonは複雑ではなく、複数の継承を持っています。主観的すぎることなく、私の質問は... 多重継承を多用するように設計されたコードの恩恵を受ける典型的な問題パターンは何ですか

2
C ++は、共通の共通の祖先を持つ複数の継承をどのように処理しますか?
私はC ++の男ではありませんが、これについて考えることを余儀なくされています。C ++では多重継承が可能ですが、C#ではできないのはなぜですか?(ダイヤモンドの問題を知っていますが、それは私がここで尋ねていることではありません)。C ++は、複数の基本クラスから継承された同一のメソッドシグネチャのあいまいさをどのように解決しますか?そして、なぜ同じデザインがC#に組み込まれていないのですか?

4
並列階層-部分的に同じ、部分的に異なる
似たような質問がたくさんあります 1、2、3、4、ただし、この質問ではnonは当てはまらないようであり、解は最適とは思われません。 これは一般的なOOPの質問であり、多態性、ジェネリック、およびミックスインが利用可能であると仮定しています。実際に使用される言語はOOP Javascript(Typescript)ですが、JavaまたはC ++でも同じ問題です。 並列クラス階層があり、同じ動作(インターフェイスと実装)を共有することもありますが、それぞれに独自の「保護された」動作があります。次のように説明します。 これは、説明のみを目的としています。実際のクラス図ではありません。それを読むには: 共通階層(中心)のすべては、Canvas(左)階層とSVG(右)階層の両方で共有されます。シェアとは、インターフェースと実装の両方を意味します。 左または右の列にのみあるものは、その階層に固有の動作(メソッドとメンバー)を意味します。例えば: 左右の階層は、まったく同じ検証メカニズムを使用しViewee.validate()ます。これは、共通の階層で単一のメソッド()として示されています。 キャンバス階層のみにメソッドがありpaint()ます。このメソッドは、すべての子に対してpaintメソッドを呼び出します。 SVG階層はのaddChild()メソッドをオーバーライドする必要がありますCompositeが、キャンバス階層の場合はそうではありません。 両側の階層の構造を混在させることはできません。工場はそれを保証します。 解決策I-継承を離れる Fowler's Tease Apart Inheritanceは、2つの類似点の間に矛盾があるため、ここでは役に立たないようです。 解決策II-ミックスイン これは私が現在考えることができる唯一のものです。2つの階層は別々に開発されますが、各レベルでクラスはクラス階層の一部ではない共通クラスに混在します。structuralフォークを省略すると、次のようになります。 各列は独自の名前空間にあるため、クラス名は競合しません。 質問 誰でもこのアプローチで障害を見ることができますか?誰もがより良い解決策を考えることができますか? 補遺 これがどのように使用されるかを示すサンプルコードを次に示します。名前空間svgは次のように置き換えられますcanvas: var iView = document.getElementById( 'view' ), iKandinsky = new svg.Kandinsky(), iEpigone = new svg.Epigone(), iTonyBlair = new svg.TonyBlair( iView, iKandinsky ), iLayer = new svg.Layer(), …

4
アーキテクチャ(リアルタイム戦略ゲームのNPC)の多重継承に代わるものはありますか?
コーディングは実際にはそれほど難しくありません。難しい部分は、理にかなっており、読みやすく、理解可能なコードを書くことです。だから、私はより良い開発者を獲得し、強固なアーキテクチャを作りたいと思っています。 それで、私はビデオゲームでNPCのアーキテクチャを作成したいと思います。これは、Starcraft、Age of Empires、Command&Conquersなどのようなリアルタイム戦略ゲームです。したがって、さまざまな種類のNPCがあります。A NPCは、これらの多くの能力(メソッド)に1を持つことができますBuild()、Farm()とAttack()。 例: 労働者がすることができますBuild()し、Farm() 戦士缶Attack() 市民缶Build()、Farm()とAttack() 漁師ができるFarm()とAttack() これまでのところすべてが明確であることを願っています。 だから今、私は私のNPCタイプとその能力を持っています。しかし、技術的/プログラム的な側面を見てみましょう。 さまざまな種類のNPCに適したプログラムアーキテクチャは何でしょうか。 さて、基本クラスを持つことができました。実際、これはDRYの原則を守る良い方法だと思います。WalkTo(x,y)すべてのNPCが移動できるため、基本クラスのようなメソッドを持つことができます。しかし今、本当の問題に取り掛かりましょう。自分の能力をどこで実装しますか?(覚えておいてください:Build()、Farm()およびAttack()) 能力は同じロジックで構成されるため、各NPC(Worker、Warrior、..)にそれらを実装することは、DRYの原則に迷惑をかける/破るでしょう。 さて、基本クラス内に能力を実装できました。NPCは、能力Xを使用することができる場合、これは検証というロジックのいくつかの種類が必要になりIsBuilder、CanBuild、..私は私が表現したいものを明確だと思います。 しかし、私はこの考えにあまり気分がよくありません。これは、機能が多すぎる肥大化した基本クラスのように聞こえます。 プログラミング言語としてC#を使用しています。したがって、ここでは多重継承はオプションではありません。手段:のような追加の基本クラスがあるFisherman : Farmer, Attackerと機能しません。

1
依存性注入にPythonのメソッド解決順序を使用する-これは悪いことですか?
私はレイモンドヘッティンガーのPyconの講演「スーパー考慮スーパー」を見て、クラスの「親」クラスを決定論的な方法で線形化するPythonのMRO(メソッド解決順序)について少し学びました。これを使用して、以下のコードのように、依存性注入を行うことができます。だから今は当然、super何にでも使いたい! 次の例では、Userクラスは、LoggingServiceとの両方から継承することで、依存関係を宣言していUserServiceます。これは特に特別なことではありません。興味深いのは、メソッド解決順序を使用して、単体テスト中に依存関係を模擬できることです。以下のコードは、モックしたいメソッドのMockUserService継承UserServiceと実装を提供するを作成します。以下の例では、の実装を提供していますvalidate_credentials。へのMockUserService呼び出しを処理validate_credentialsするにUserServiceは、MROの前に配置する必要があります。これは、User呼び出されるラッパークラスを作成し、MockUserそれをUserand から継承させることで行われMockUserServiceます。 これを実行するMockUser.authenticateと、次に、への呼び出しがメソッド解決順序のsuper().validate_credentials() MockUserService前UserServiceにあり、validate_credentialsこの実装の具体的な実装が提供されるため、これが使用されます。いいですね- UserService単体テストでうまく模倣しました。UserServiceコストのかかるネットワークやデータベースの呼び出しが発生する可能性があることを考慮してください。これにより、レイテンシ係数が削除されました。また、UserServiceライブ/製品データに触れるリスクもありません。 class LoggingService(object): """ Just a contrived logging class for demonstration purposes """ def log_error(self, error): pass class UserService(object): """ Provide a method to authenticate the user by performing some expensive DB or network operation. """ def validate_credentials(self, username, password): print('> UserService::validate_credentials') return username == …

2
Pythonの継承は「is-a」の継承スタイルですか、それともコンポジションスタイルですか?
Pythonが複数の継承を許可する場合、Pythonの慣用的な継承はどのように見えますか? Javaのように単一継承の言語では、あるオブジェクトが別のオブジェクトの「is-a」であり、オブジェクト間でコードを共有したい場合(親オブジェクトから子オブジェクトまで)は、継承が使用されます。たとえば、それDogはAnimal: public class Animal {...} public class Dog extends Animal {...} しかし、Pythonは多重継承をサポートしているため、他の多くのオブジェクトを組み合わせてオブジェクトを作成できます。以下の例を検討してください。 class UserService(object): def validate_credentials(self, username, password): # validate the user credentials are correct pass class LoggingService(object): def log_error(self, error): # log an error pass class User(UserService, LoggingService): def __init__(self, username, password): self.username = username self.password = password …

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