manとchild共通点があり、どのように異なるか。
class Person {
name: string;
age: number;
}
class child extends Person {}
class man implements Person {}
extends
意味:新しいクラスは子です。継承には利点があります。すべてのプロパティとメソッドが親としてあります。これらのいくつかをオーバーライドして、新しいものを実装できますが、親のものはすでに含まれています。
implements
意味:新しいクラスは、同じ "shape"、それは子ではありません。 Person
とは異なる親を持つことに関係なく、Person
が必要な任意のメソッドに渡すことができます。
OOP(C#、Javaなどの言語)を使用します
extends
継承から利益を得る( wiki を参照)。小さな引用:
...ほとんどのクラスベースのオブジェクト指向言語の継承は、1つのオブジェクトが親オブジェクトのすべてのプロパティと動作を取得するメカニズムです。継承により、プログラマは次のことができます。既存のクラスに基づいて構築されるクラスを作成する...
implements
は、ポリモーフィズムの場合により多くなります( wiki を参照)小さな引用:
...ポリモーフィズムは、異なるタイプのエンティティへの単一のインターフェースの提供です...
したがって、class Man
のまったく異なる継承ツリーを持つことができます。
class Man extends Human ...
しかし、異なる型のふりをすることができると宣言する場合は、Person
:
class Man extends Human
implements Person ...
..その後、Person
が必要な場所であればどこでも使用できます。 Personsの"interface"
(つまり、すべてのパブリックなものを実装する)を満たす必要があります。
implement
他のクラス?それは本当にクールなものですJavascript Nice face(利点の1つ)は、ダックタイピングの組み込みサポートです( wikiを参照 )。小さな引用:
「それがアヒルのように歩き、それがアヒルのように鳴るなら、それはアヒルでなければなりません。」
そのため、Javascriptでは、2つの異なるオブジェクト...に1つの類似したメソッド(e.g。render()
)がある場合、それらを期待する関数に渡すことができます。
function(engine){
engine.render() // any type implementing render() can be passed
}
それを失わないように-TypeScriptでも同じことができます-より多くの型付きサポートがあります。そして、それはどこです
class implements class
意味があるところに役割がある
OOP言語ではC#
として...それを行う方法はありません...
クラスを拡張するインターフェイス
インターフェイス型がクラス型を拡張すると、クラスのメンバーは継承されますが、実装は継承されません。インターフェースが実装を提供せずにクラスのすべてのメンバーを宣言したかのようです。インターフェイスは、基本クラスのプライベートおよび保護されたメンバーも継承します。つまり、プライベートまたは保護されたメンバーを持つクラスを拡張するインターフェイスを作成する場合、そのインターフェイスタイプはそのクラスまたはそのサブクラスによってのみ実装できます。
これは、大きな継承階層があるが、特定のプロパティを持つサブクラスのみでコードが機能するように指定する場合に役立ちます。サブクラスは、基本クラスから継承する以外に関連する必要はありません。例えば:
class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control { select() { } } class TextBox extends Control { select() { } } class Image extends Control { } class Location { select() { } }
それで、
extends
は、すべてを親から取得することを意味しますimplements
は、インターフェイスの実装に似ています。子オブジェクトは、親であるふりをすることができます...しかし、それは実装を取得しませんTypeScript(およびその他のOO言語)には、クラスとインターフェイスがあります。
インターフェースには実装がありません。これは、このタイプのメンバー/メソッドの「契約」にすぎません。
例えば:
interface Point {
x: number;
y: number;
distance(other: Point): number;
}
このPoint
インターフェースを実装するインスタンスには、タイプ番号の2つのメンバー:x
およびy
と、別のdistance
インスタンスを受け取り、Point
を返す1つのメソッドnumber
が必要です。
インターフェースはこれらのいずれも実装していません。
クラスは実装です:
class PointImplementation implements Point {
public x: number;
public y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
public distance(other: Point): number {
return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
}
}
( 遊び場のコード )
この例では、Person
クラスを拡張するときにクラスとして1回、実装するときにインターフェイスとして1回扱います。
あなたのコード:
class Person {
name: string;
age: number;
}
class Child extends Person {}
class Man implements Person {}
次のようなコンパイルエラーがあります。
クラス「Man」は、インターフェース「Person」を誤って実装します。
タイプ 'Man'にプロパティ 'name'がありません。
そして、それはインターフェースに実装がないためです。
クラスをimplement
にすると、実装なしでその「契約」を取得するだけなので、これを行う必要があります。
class NoErrorMan implements Person {
name: string;
age: number;
}
( 遊び場のコード )
一番下の行は、ほとんどの場合、それをextend
ではなく、implement
別のクラスにしたいということです。
@ nitzan-tomerからのすばらしい回答です!私を大いに助けてくれました...彼のデモを少し拡張しました:
IPoint interface;
Point implements IPoint;
Point3D extends Point;
そして、IPoint型を期待する関数での動作。
したがって、これまでに学んだことや経験則として使用していることは、ジェネリック型を期待するクラスとメソッドを使用している場合は、期待される型としてインターフェイスを使用することです。そして、親または基本クラスがそのインターフェースを使用していることを確認してください。そうすれば、インターフェイスを実装する限り、サブクラスのすべてのサブクラスを使用できます。
extends
は継承に焦点を当て、implements
はインターフェイスまたはクラスに関係なく制約に焦点を当てます。