ウィキペディアでは、仮想メソッドを次のように定義しています。
オブジェクト指向プログラミングでは、仮想関数または仮想メソッドは、同じ多型の動作を提供するために、同じシグネチャを持つ関数によって継承クラス内でその動作をオーバーライドできる関数またはメソッドです。
定義によれば、Javaのすべての非静的メソッドは、最終メソッドとプライベートメソッドを除き、デフォルトで仮想メソッドです。ポリモーフィックな振る舞いで継承できないメソッドは仮想メソッドではありません。
Javaの静的メソッドはオーバーライドできません。したがって、静的メソッド自体はfinalメソッドと同じように動作するため、Javaでstaticメソッドをfinalとして宣言しても意味がありません。それらは、同じシグネチャを持つメソッドによってサブクラスで単に非表示にすることができます。静的メソッドがポリモーフィックな振る舞いを決して持つことができないため、それは明白です。オーバーライドされるメソッドは、ポリモーフィズムを達成する必要がありますが、静的メソッドの場合はそうではありません。
前の段落から、重要な結論を導き出すことができます。C ++のすべてのメソッドはデフォルトで静的です。C++のメソッドは、スーパークラスで明示的にvirtualと宣言されるまで、ポリモーフィックに動作できないためです。対照的に、final、static、privateメソッドを除くJavaのすべてのメソッドは、デフォルトでポリモーフィックな動作をするため、デフォルトで仮想です(Javaでメソッドを明示的に仮想として宣言する必要はなく、その結果、Javaには「virtual」のようなキーワードがありません。 )。
次に、インスタンス変数(静的も)がJavaの次の簡単な例から多態的に動作できないことを示しましょう。
class Super
{
public int a=5;
public int show()
{
System.out.print("Super method called a = ");
return a;
}
}
final class Child extends Super
{
public int a=6;
@Override
public int show()
{
System.out.print("Child method called a = ");
return a;
}
}
final public class Main
{
public static void main(String...args)
{
Super s = new Child();
Child c = new Child();
System.out.println("s.a = "+s.a);
System.out.println("c.a = "+c.a);
System.out.println(s.show());
System.out.println(c.show());
}
}
上記のコードスニペットによって生成される出力は次のとおりです。
sa = 5 ca = 6 a と呼ばれる子メソッド= 6 a = 6と呼ばれる子メソッド
この例では、コールの両方s.show()
とc.show()
に加えられたshow()
型の変数を通じて方法Super
とタイプのChild
それぞれは、起動show()
方法をChild
クラス。これはshow()
、Child
クラスのメソッドはクラスのshow()
メソッドをオーバーライドすることを意味しますSuper
。これは、どちらも同じシグネチャを持っているためです。
ただし、これa
は両方のクラスで宣言されたインスタンス変数には適用できません。この場合には、s.a
を指すことになるa
でSuper
クラスとディスプレイ5
とc.a
を指すことになるa
でChild
クラスおよび表示6
という意味a
でChild
(および非静的メソッドに起こったようにオーバーライドしない)クラスだけ皮a
内Super
クラス。
この長い議論の後、1つだけ質問があります。インスタンス変数(およびその他)がオーバーライドされないのはなぜですか?そのようなメカニズムを実装する特別な理由は何ですか?オーバーライドされた場合、利点または欠点はありますか?
オーバーライドの目的は、署名を変更せずに機能を変更することだと思います。これはメソッドにのみ関連します。メソッドは同じシグネチャを持つ可能性がありますが、動作が異なります。フィールドには「シグネチャ」のみがあり、タイプと名前にも限定されています。これらには動作がないため、何もオーバーライドできません。
フィールドを「オーバーライド」できない他の理由は、フィールドは通常プライベートである(またはプライベートである必要がある)ため、実際にはクラス実装の悲惨な詳細であるためです。ただし、メソッドはクラスの外部インターフェースを表します。モジュール間の関係を変更せずにモジュールの機能を簡単に変更できるように、この外部インターフェースは多相性をサポートする必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加