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

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

14
この「継承よりも有利な構成」という概念はどこから来たのでしょうか?
過去数か月で、「継承よりも好意的な構成」というマントラがどこからともなく生まれ、プログラミングコミュニティ内でほぼ何らかのミームになったようです。そして、それを見るたびに、私は少し神秘的になります。誰かが「ハンマーよりもドリルを好む」と言ったようです。私の経験では、構成と継承は異なるユースケースを持つ2つの異なるツールであり、それらを互換性があり、一方が本質的に他方より優れているかのように扱うことは意味がありません。 また、なぜ継承が悪く、構成が良いのかについての本当の説明は見ていません。信仰によって受け入れられるだけなのでしょうか?リスコフ置換とポリモーフィズムには、明確で明確な利点があり、IMOはオブジェクト指向プログラミングを使用するすべてのポイントを構成します。構成を優先して破棄する理由を説明する人はいません。 この概念がどこから来たのか、そしてその背後にある理論的根拠は誰か知っていますか?

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の観点、またはより純粋な例の観点から考えることもできます。

5
継承よりも合成を優先する必要があるのはなぜですか?
私は常に、構成が継承よりも優先されることを読みました。種類とは異なり、上のブログの記事は、例えば、相続上の組成物を用いて提唱したが、私は多型が達成されたかを確認することはできません。 しかし、私は人々が作曲を好むと言うとき、彼らは本当に作曲とインターフェース実装の組み合わせを好むことを意味すると感じています。継承なしでどのようにポリモーフィズムを取得するのですか? 継承を使用する具体的な例を次に示します。構成を使用するためにこれをどのように変更しますか? Class Shape { string name; public: void getName(); virtual void draw()=0; } Class Circle: public Shape { void draw(/*draw circle*/); }

12
SetWidthメソッドとSetHeightメソッドをオーバーライドすると、Rectangleから継承するSquareに問題があるのはなぜですか?
SquareがRectangleのタイプである場合、なぜSquareはRectangleを継承できないのですか?それとも、なぜそれが悪いデザインですか? 私は人々が言うのを聞いたことがあります: SquareをRectangleから派生させた場合、Squareは予想される任意の場所で使用できるはずです。 ここで問題は何ですか?そして、なぜSquareはあなたが長方形を期待するどこでも使えるのでしょうか?Squareオブジェクトを作成し、SquareのSetWidthメソッドとSetHeightメソッドをオーバーライドする場合にのみ使用できるのは、なぜ問題があるのでしょうか? Rectangle基本クラスにSetWidthメソッドとSetHeightメソッドがあり、Rectangle参照がSquareを指している場合、SetWidthとSetHeightは、一方を設定するともう一方がそれに合わせて変更されるため、意味がありません。この場合、SquareはRectangleによるLiskov Substitution Testに失敗し、RectangleからSquareを継承させるという抽象化は悪いものです。 誰かが上記の議論を説明できますか?繰り返しますが、SquareでSetWidthおよびSetHeightメソッドをオーバーライドすると、この問題は解決しませんか? 私も聞いた/読んだ: 実際の問題は、長方形をモデリングするのではなく、「再整形可能な長方形」、つまり作成後に幅または高さを変更できる長方形をモデリングすることです(それでも同じオブジェクトと見なします)。このように長方形クラスを見ると、正方形は「再成形可能な長方形」ではないことが明らかです。なぜなら、正方形は形を変えられず、依然として正方形であるためです(一般的に)。数学的には、数学的文脈では可変性は意味をなさないため、問題は見られません。 ここでは、「サイズ変更可能」が正しい用語だと思います。長方形は「サイズ変更可能」であり、正方形も同様です。上記の議論に何か欠けていますか?正方形は、任意の長方形と同様にサイズ変更できます。

7
C#で拡張メソッドを持つインターフェイスの代わりに抽象クラスを使用する場合
「抽象クラス」と「インターフェース」は類似した概念であり、インターフェースはより抽象的な概念です。1つの差別化要因は、抽象クラスが必要なときに派生クラスのメソッド実装を提供することです。ただし、C#では、この差別化要因は、インターフェイスメソッドの実装を提供できる拡張メソッドの最近の導入によって削減されました。別の差別化要因は、クラスが1つの抽象クラスのみを継承できる(つまり、多重継承がない)が、複数のインターフェイスを実装できることです。これにより、インターフェイスの制限が緩和され、柔軟性が高まります。それでは、C#では、拡張メソッドを備えたインターフェイスの代わりに抽象クラスをいつ使用すべきでしょうか? インターフェイス+拡張メソッドモデルの注目すべき例はLINQです。ここではIEnumerable、多数の拡張メソッドを介して実装されるすべてのタイプに対してクエリ機能が提供されます。

11
プログラムを複数のクラスに分割するのが良いのはなぜですか?[閉まっている]
私はまだ高校生(10年生)で、学校で実際のコンピューターコースをまだ受講していません。これまでにやったことはすべて本を通してです。これらの本は、継承などの概念を教えてくれましたが、プログラムを複数のクラスに分割するとどのように役立ちますか?本は私に決して言わなかった。 主に最近のプロジェクトのためにこれを求めています。これはアーケードビデオゲームで、一部の人が言っているようにFlashゲームのようなものです(Flashゲームとは何なのかはわかりませんが)。事は、それはただ一つのクラスです。1つのクラスで完全に正常に動作します(ただし、時折ラグが発生します)。だから、私はそれを複数のクラスに分割することがどのように役立つかを尋ねています。 このプロジェクトはJavaで行われ、記録のために私がプロジェクトに取り組んでいるのは私だけです。

17
オブジェクト指向プログラミングは、雇用会社が配置するのと同じくらい重要ですか?[閉まっている]
私はちょうど(コンピューティングの)修士号を取得し、仕事に応募しています。多くの企業がオブジェクト指向の理解を特に求めていることに気付きました。人気のあるインタビューの質問は、継承、ポリモーフィズム、アクセサーなどに関するものです。 オブジェクト指向は本当に重要ですか?私はCでのプログラミングの仕事の面接さえ受けましたが、面接の半分はオブジェクト指向でした。 現実の世界では、実際のアプリケーションの開発において、ほとんど常にオブジェクト指向が使用されていますか?ポリモーフィズムのような主要な機能はLOTを使用していますか? 私の質問は私の弱点の一つから来ていると思います。私はオブジェクト指向について知っていますが、私はそれを私のプログラムに大いに組み込むことができないようです。

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

3
型システムとは何ですか?
バックグラウンド 私はサイドプロジェクトとして言語を設計しています。動作するアセンブラー、静的アナライザー、それに仮想マシンがあります。構築したインフラストラクチャを使用して、重要なプログラムを既にコンパイルおよび実行できるため、大学でプレゼンテーションを行うことを考えました。 私の話の中で、私はVMが型システムを提供することについて言及しました、「あなたの型システムは何のためにあるのですか?」答えた後、私は質問をする人に笑われました。 したがって、この質問をすることで評判を失うことはほぼ確実ですが、プログラマーに頼ります。 私の理解 私が理解しているように、型システムはプログラム内のエンティティに関する追加情報の層を提供するために使用されるため、ランタイム、コンパイラー、またはその他の機械は、操作対象のビット文字列をどう処理するかを認識します。また、コントラクトの維持にも役立ちます。コンパイラ(またはコードアナライザー、ランタイム、またはその他のプログラム)は、プログラマーが期待する値でプログラムが動作することをいつでも検証できます。 タイプは、それらの人間のプログラマーに情報を提供するためにも使用できます。たとえば、次の宣言を見つけます。 function sqrt(double n) -> double; これよりも便利 sqrt(n) 前者は多くの情報を提供します:sqrt識別子は関数であり、double入力として単一のものを取り、double出力として別のものを生成します。後者は、おそらく単一のパラメーターを取る関数であることを示しています。 私の答え それで、「あなたのタイプシステムは何のためですか?」私は次のように答えました: 型システムは動的です(型は値を保持する変数ではなく値に割り当てられます)が、意外な強制ルールがなければ強力です(互換性のない型を表すため、文字列を整数に追加できませんが、浮動小数点数に整数を追加できます) 。 タイプシステムは、命令のオペランドが有効であることを確認するためにVMによって使用されます。また、プログラマーは、関数に渡されたパラメーターが有効(つまり、正しい型)であることを確認するために使用できます。 型システムは、サブタイピングと多重継承をサポートしています(プログラマーは両方の機能を使用できます)。オブジェクトのメソッドの動的ディスパッチが使用される場合、型は考慮されます。 次の質問は、「タイプは値にどのように割り当てられますか?」でした。そこで、すべての値がボックス化され、タイプの名前、応答するメッセージ、および継承するタイプに関する情報を提供するタイプ定義構造を指すポインターがあることを説明しました。 その後、私は笑われ、「それは本当のタイプシステムではない」というコメントで私の答えは却下されました。 だから-私が説明したものが「実際のタイプシステム」として適格でない場合、どうなりますか?その人は、私が提供するものを型システムと見なすことができないということは正しいのですか?

8
LSP vs OCP / Liskov Substitution VS Open Close
私は、OOPの固い原則を理解しようとしていますが、LSPとOCPにはいくつかの類似点があるという結論に達しました(詳しくは言いませんが)。 オープン/クローズの原則には、「ソフトウェアエンティティ(クラス、モジュール、関数など)は拡張のために開かれているが、変更のために閉じられている必要があります」と記述されています。 簡単な言葉で言えば、LSPはのFooインスタンスをBar派生元のインスタンスに置き換えることができFoo、プログラムはまったく同じように機能することを示しています。 私はプロのOOPプログラマーではありませんが、LSPはBar、から派生しFooたものがその中の何も変更せず、拡張する場合にのみ可能であるように思われます。つまり、特定のプログラムのLSPはOCPが真の場合にのみ真であり、OCPはLSPが真の場合にのみ真です。それは、それらが等しいことを意味します。 私が間違っている場合は修正してください。これらのアイデアを本当に理解したいです。答えてくれてありがとう。

5
クラスを継承し、プロパティを追加しないのはなぜですか?
私たちの(かなり大きな)コードベースで、次のような継承ツリーを見つけました。 public class NamedEntity { public int Id { get; set; } public string Name { get; set; } } public class OrderDateInfo : NamedEntity { } 私が集めることができるものから、これは主にフロントエンドでのものをバインドするために使用されます。 私にとっては、genericに依存するのではなく、クラスに具体的な名前を付けるため、これは理にかなっていますNamedEntity。一方、追加のプロパティを持たないクラスは数多くあります。 このアプローチには欠点がありますか?

11
コンストラクターのみのサブクラス:これはアンチパターンですか?
私は同僚と議論をしていましたが、最終的にはサブクラス化の目的に関して直感が矛盾することになりました。私の直感では、サブクラスの主な機能がその親の限られた範囲の値を表現することであれば、おそらくサブクラスであってはならないということです。彼は反対の直観を主張しました:サブクラス化はオブジェクトがより「特定的」であることを表し、したがってサブクラス関係がより適切であるということです。 私の直感をより具体的に言うと、親クラスを拡張するサブクラスがあるが、サブクラスがオーバーライドする唯一のコードがコンストラクターである場合(そう、コンストラクターは一般に「オーバーライド」しないことを知っています。本当に必要だったのは、ヘルパーメソッドです。 たとえば、このやや現実的なクラスを考えてみましょう。 public class DataHelperBuilder { public string DatabaseEngine { get; set; } public string ConnectionString { get; set; } public DataHelperBuilder(string databaseEngine, string connectionString) { DatabaseEngine = databaseEngine; ConnectionString = connectionString; } // Other optional "DataHelper" configuration settings omitted public DataHelper CreateDataHelper() { Type dataHelperType = DatabaseEngineTypeHelper.GetType(DatabaseEngine); DataHelper …


11
抽象クラス/メソッドは廃止されていますか?
以前は、多くの抽象クラス/メソッドを作成していました。その後、インターフェイスの使用を開始しました。 現在、インターフェイスが抽象クラスを廃止していないかどうかはわかりません。 完全に抽象クラスが必要ですか?代わりにインターフェースを作成してください。いくつかの実装を含む抽象クラスが必要ですか?インターフェイスを作成し、クラスを作成します。クラスを継承し、インターフェイスを実装します。追加の利点は、一部のクラスが親クラスを必要とせず、インターフェイスを実装するだけであることです。 それでは、抽象クラス/メソッドは廃止されていますか?

3
「継承を超える構成」は「ドライ原則」に違反していますか?
たとえば、他のクラスを拡張するクラスがあるとします。 public class LoginPage { public String userId; public String session; public boolean checkSessionValid() { } } およびいくつかのサブクラス: public class HomePage extends LoginPage { } public class EditInfoPage extends LoginPage { } 実際、サブクラスにはオーバーライドするメソッドがありません。また、一般的な方法でHomePageにアクセスしません。つまり、次のようなことはしません。 for (int i = 0; i < loginPages.length; i++) { loginPages[i].doSomething(); } ログインページを再利用したいだけです。ただし、https: //stackoverflow.com/a/53354によると、インターフェイスLoginPageは必要ないため、ここでは構成を優先する必要があります。したがって、ここでは継承を使用しません。 public class HomePage …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.