functionparentClass() {
/ / プライベート フィールド
var x = "私はparentClass フィールドです!";
// プライベート メソッド
function method1() {
alert(x); m aparentClass メソッド!");
}
// public field
this.x = "I'm aparentClass object field!";
// public メソッド
this.method1 = function( ) {
alert(x);
method1();
}
}
parentClass.prototype.method = function () {
alert("私はparentClassのプロトタイプメソッドです!");
}
parentClass.staticMethod = function () {
alert("私はparentClassの静的メソッドです! ");
}
function subClass() {
// 継承
parentClass.call(this);
// プライベート フィールド
var x = "私はサブクラスのフィールドです!";
// プライベート メソッド
function method2() {
alert(x);
alert("私はサブクラスのメソッドです!"); >}
// パブリック フィールド
this.x = "私はサブクラス オブジェクト フィールドです!";
// パブリック メソッド
this.method2 = function() {
alert( x) ;
alert(this.x);
メソッド 2();
this.method3 = function() {
メソッド 1();
// テスト
var o = new subClass();
alert(oinstanceofparentClass); //false
alert(oinstanceofsubClass); 🎜>
alert(o.constructor); // function subClass() {...}
o.method1(); // 私はparentClassフィールドです! '私は subClass オブジェクト フィールドです!
// 私はparentClass メソッドです!
o.method2(); 🎜> // 私は subClass オブジェクト フィールドです!
// 私は subClass メソッドです!
//エラー !!
o.method3(); // エラー !!!
上記の例は、呼び出し継承メソッドを使用して継承を実装する方法をよく示しています。
呼び出し継承を使用するための重要なステップは 1 つだけです。
サブクラスが定義されたら、親クラスの call メソッドを通じてサブクラスの this ポインターを渡します。親クラスのメソッドを子クラスのコンテキストで実行します。
このようにして、親クラス内のこのメソッドを通じて定義された親クラス内のすべてのパブリック インスタンス メンバーがサブクラスに継承されます。
instanceof 演算子で判断すると、サブクラスのインスタンス化されたオブジェクトは、親クラスではなく、サブクラスにのみ属します。
サブクラスのインスタンス化されたオブジェクトのコンストラクター プロパティを見ると、その親クラスの定義ではなく、サブクラスの定義が表示されます。
次に、o.method1() と o.method2() を呼び出した結果は、プロトタイプ継承を呼び出した結果と同じであり、説明されている問題も同じであるため、ここでは繰り返しません。
o.method() を呼び出した結果から、親クラスのプロトタイプで定義されたメソッドがサブクラスに継承されないことがわかります。
o.method3() を呼び出した結果から、サブクラスで定義されたインスタンス メソッドは、親クラスで定義されたプライベート インスタンス メンバーにアクセスできないことがわかります。
最後に、subClass.staticMethod() を呼び出した結果から、静的メンバーも継承されないことがわかります。
最後に、この例には反映されていないもう 1 つの点があります。つまり、継承メソッドを呼び出すことで多重継承を実現できます。つまり、サブクラスは、このメソッドを通じて、親クラス内で定義されているすべてのパブリック インスタンス メンバーを複数の親クラスから継承できます。
JavaScript は、弱い型付けの言語として、豊富なポリモーフィズムを提供します。JavaScript のポリモーフィズムは、他の強く型付けされたオブジェクト指向言語に匹敵しません。
ポリモーフィズム
オーバーロードと上書き
まず、オーバーロードと上書きの違いについて説明します。過負荷を意味する英語はオーバーロード、カバレッジを意味する英語はオーバーライドです。インターネット上のほとんどの人がオーバーライドをオーバーロードとみなしていることがわかりましたが、それは間違いです。オーバーロードとオーバーライドには違いがあります。
オーバーロードとは、同じ名前の関数 (ここには関数も含まれることに注意してください) またはメソッドが複数の実装を持つことができ、それらはパラメーターのタイプやパラメーターの数によって区別されることを意味します。
上書きの意味は、サブクラスが親クラスのメソッドと同じ名前、同じパラメータの型と番号を持つメソッドを定義できることです。これらのメソッドは、定義された後、インスタンス化で親クラスに継承されます。同じ名前のこれらのメソッドは非表示になります。
オーバーロード
JavaScript の関数のパラメーターは型指定されず、パラメーターの数は任意ですが、たとえば、
function add(a, b) {
return a b;
}
このように関数を呼び出しても、任意の数のパラメーターを指定して呼び出すことができます。もちろん、パラメーターの型も任意です。エラーが発生するかどうかは、この関数で実行される内容によって決まります。JavaScript は、指定したパラメーターの数や種類に基づいてどの関数を呼び出しているかを判断しません。
したがって、多重定義されたメソッドを定義するには、厳密に型指定された言語のように行うことはできません。ただし、オーバーロードを実装することはできます。これは、関数の argument プロパティを通じて行われます。例:
function add() {
var sum = 0;
for (var i = 0; i < argument.length; i ) {
sum = argument[i]>}
return sum; }
このようにして、任意の数のパラメーターを使用して加算関数をオーバーロードできます。
もちろん、instanceof またはコンストラクターを使用して関数内の各パラメーターの型を決定し、後で実行する操作を決定し、より複雑な関数またはメソッドのオーバーロードを実装することもできます。つまり、JavaScript のオーバーロードは、ユーザー自身が argument 属性を操作して関数内に実装します。
オーバーライド
オーバーライドを実装することも簡単です。例:
functionparentClass() {
this.method = function() {
alert("parentClass メソッド");
}
}
function subClass () {
this .method = function() {
alert("subClass メソッド");
}
}
subClass.prototype = newparentClass();プロトタイプ.constructor = subClass;
var o = 新しい subClass();
このように、サブクラスで定義されたメソッドは、親クラスから継承されたメソッドをオーバーライドします。
このように上書きすれば良いのではないかと言われるかもしれませんが、Javaではオーバーライドされたメソッドの中でオーバーライドされたメソッド(親クラスのメソッド)を呼び出すことができます。また、非常に簡単で、Java よりも柔軟です。Java には、オーバーライドされたメソッドをオーバーライドするメソッド内で、スーパーを使用してのみオーバーライドされたメソッドを呼び出すことができるという制限があります。これを実現できるだけでなく、サブクラスのすべてのメソッドが親クラスでオーバーライドされたメソッドを呼び出すようにすることもできます。以下の例を見てください。
functionparentClass( ) {
this.method = function() {
alert("parentClass メソッド");
}
}
function subClass() {
var メソッド = this.method;
this .method = function() {
method.call(this);
alert("サブクラスメソッド");
}
}
subClass.prototype = newparentClass( );
subClass.prototype.constructor = subClass;
var o = new subClass();
オーバーライドするメソッドを定義する前にプライベート変数を定義し、その変数に親クラスで定義されたオーバーライドされるメソッドを代入すると、後で引き続きそのメソッドを呼び出すことができ、このメソッドはプライベートである限り、これは非常に簡単です。サブクラスの場合 オブジェクトは非表示になります。これは、他の高級言語で実装されているカバレッジと一致しています。
最後に、オーバーライド メソッドでこのメソッドを呼び出すときは、call メソッドを使用して実行コンテキストをこれに変更する必要があることに注意してください (ただし、この例では必要ありません)。このメソッドを直接呼び出すと、実行コンテキストはグローバル オブジェクトになります。