[解決済み] 抽象クラス vs. インターフェース vs. ミキシン
質問
の違いについて、どなたか教えてください。 抽象クラス , インターフェース そして ミックスイン ? 私は自分のコードで前にそれぞれを使用したことがありますが、技術的な違いがわかりません。
どのように解決するのですか?
抽象クラス
抽象クラスは、インスタンス化されることを想定していないクラスです。抽象クラスは、実装を持たない、いくつかの実装を持つ、またはすべての実装を持つことができます。抽象クラスは、そのサブクラスが共通の(デフォルトの)実装を共有できるように設計されています。抽象クラスの(擬似的な)例としては、次のようなものがあります。
abstract class Shape {
def abstract area(); // abstract (unimplemented method)
def outline_width() = { return 1; } // default implementation
}
サブクラスは次のようになります。
class Rectangle extends Shape {
int height = width = 5;
def override area() = { return height * width; } // implements abstract method
// no need to override outline_width(), but may do so if needed
}
可能な使用法
def main() = {
Shape[] shapes = { new Rectangle(), new Oval() };
foreach (s in shapes) {
print("area: " + s.area() + ", outline width: " + s.outline_width());
}
}
サブクラスが未実装のメソッドをオーバーライドしない場合、それはまた抽象クラスです。
インターフェース
一般的なコンピュータサイエンスの用語では、インターフェイスとはクライアントに対して公開されるプログラムの部分のことを指します。パブリッククラスやメンバはインターフェイスの例です。
JavaとC#では、特別な
interface
キーワードがあります。これらは多かれ少なかれ、実装を持たない抽象的なクラスです。(定数、ネストされたクラス、明示的な実装、アクセス修飾子については、ここでは触れませんが、トリックがあります)。Javaでは、この「実装を持たない」という部分はもう通用しませんが、デフォルトのメソッドが追加されました。その
interface
キーワードはインターフェースの概念を再定義したものと見ることができます。
シェイプの例に戻ると
interface Shape {
def area(); // implicitly abstract so no need for abstract keyword
def outline_width(); // cannot implement any methods
}
class Rectangle implements Shape {
int height = width = 5;
def override area() = { return height * width; }
def override outline_width() = { return 1; } // every method in interface must be implemented
}
def main() = {
Shape[] shapes = { new Rectangle(), new Oval() };
foreach (s in shapes) {
print("area: " + s.area() + ", outline width: " + s.outline_width());
}
}
JavaとC#は実装を伴うクラスの多重継承を認めていませんが、インターフェースの多重実装は認めています。JavaとC#では、インターフェイスを回避策として 死のダイヤモンド問題 に対する回避策としてインターフェイスを使用しています(適切に対処すればそれほど致命的ではありません)。
ミキシン
mixin (traitと呼ばれることもあります) は抽象クラスを多重継承させることができます。ミキシンは多重継承のような恐ろしい関連性を持たないので(C++の狂気のせい)、人々はより快適にそれらを使用することができます。しかし、それをサポートする言語は、C++よりもエレガントな方法でそれを軽減しているので、より良いものとして認識されています。
Mixin は、以下のようなインターフェイスとして歓迎されています。
動作の再利用
,
より柔軟
インターフェース、そして
より強力な
インタフェースがあります。これらはすべて
interface
という用語があり、JavaとC#のキーワードを参照しています。
Mixinはインターフェースではありません。
多重継承です。もっときれいな名前です。
これはミキシンが悪いと言っているのではありません。多重継承が悪いわけではありません。C++が多重継承を解決する方法について、みんなが大騒ぎしているのです。
うんざりするほど古いシェイプの例について
mixin Shape {
def abstract area();
def outline_width() = { return 1; }
}
class Rectangle with Shape {
int height = width = 5;
def override area() = { return height * width; }
}
def main() = {
Shape[] shapes = { new Rectangle(), new Oval() };
foreach (s in shapes) {
print("area: " + s.area() + ", outline width: " + s.outline_width());
}
}
抽象クラスの例と違いがないことにお気づきでしょう。
もう一つおまけの豆知識として、C#はバージョン3.0からmixinをサポートしています。インターフェイスの拡張メソッドでミキシンを行うことができます。以下は、本物の(!)C#コードのmixinスタイルによるShapeの例です。
interface Shape
{
int Area();
}
static class ShapeExtensions
{
public static int OutlineWidth(this Shape s)
{
return 1;
}
}
class Rectangle : Shape
{
int height = 5;
int width = 5;
public int Area()
{
return height * width;
}
}
class Program
{
static void Main()
{
Shape[] shapes = new Shape[]{ new Rectangle(), new Oval() };
foreach (var s in shapes)
{
Console.Write("area: " + s.Area() + ", outline width: " + s.OutlineWidth());
}
}
}
関連
-
[解決済み] インターフェースと抽象クラスの違いは何ですか?
-
[解決済み] オブジェクト名の前のシングルアンダーコアとダブルアンダーコアの意味は何ですか?
-
[解決済み] インターフェースと抽象クラス(一般的なOO)
-
[解決済み] mixinとは何か、なぜ有用なのか?
-
[解決済み] Java のコア・ライブラリにおける GoF デザイン・パターンの例
-
[解決済み] C#のインターフェイス。暗黙の実装と明示の実装
-
[解決済み] いつ使うか。Java 8+のインターフェイスのデフォルトメソッドと、抽象的なメソッドの比較
-
[解決済み】TypeScriptのインターフェースと型について
-
[解決済み] オブジェクト指向分析・設計によるエレベータのモデル化 [終了しました]
-
[解決済み] 多重継承の具体的な問題点は何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] インターフェースと抽象クラスの違いは何ですか?
-
[解決済み] 抽象クラスの代わりにインターフェイスを使用する場合とその逆は?
-
[解決済み】依存関係逆転の原則とは何ですか、なぜそれが重要なのですか?
-
[解決済み] プライベートとプロテクト-ビジビリティ・グッド・プラクティスの懸念点【終了しました
-
[解決済み] 継承と集計の比較【終了しました
-
[解決済み] ミキシン vs. トレイツ
-
[解決済み] Scalaでコンパニオン・オブジェクトを持つ根拠は何ですか?
-
[解決済み] protected なメンバ変数を使うべきですか?
-
[解決済み] よりよいオブジェクト指向プログラミングを実践するには?[終了しました]
-
[解決済み] typescript で基底クラスのコンストラクタでオーバーライドされたメソッドを呼び出す