Java多形性の定義と用法の実例の詳細解

6709 ワード

本論文の実例はJava多形性定義と用法を述べている。皆さんに参考にしてあげます。具体的には以下の通りです。
多形性は通過します
1インターフェースと実装インターフェースは、同じ方法のいくつかの異なるクラスの実装をカバーします。
2親類と親類を継承し、同じ方法のいくつかの異なるサブクラスをカバーして実現した。
一、基本概念
多形性:どのような挙動に応答するかは、オブジェクトにメッセージを送る。サブクラスのオブジェクトをスーパークラスのオブジェクトに変数を参照することによって、動的な方法の呼び出しが実現されます。
javaのこのようなメカニズムは、変数がサブクラスのオブジェクトを参照する際に、参照対象のタイプが変数のタイプではなく、誰のメンバーメソッドを呼び出すかを決定しているが、この呼び出し方法は、スーパークラスで定義されている必要があります。つまり、布団タイプのカバー方法です。
aがクラスAの1つの参照である場合、aはクラスAの一例、またはクラスAの1つのサブクラスを指すことができる。
aがインターフェースAの1つの参照である場合、aはインターフェースAを実装した1つのクラスの実例を指す必要がある。
二、Java多形実現メカニズム
SUNの現在のJVM実現メカニズムは、クラスの実例の引用はハンドルの針を指しています。このハンドルはペアのポインタです。
一つのポインタは一つの表を指していますが、実はこの表にも二つのポインタがあります。
もう一つのポインタは、javaスタックから割り当てられたメモリ空間を指します。
三、まとめ
1、サブクラスのオブジェクトをスーパークラスのオブジェクトに値付けして変数を参照することによって、動的な方法の呼び出しが行われます。

DerivedC c2=new DerivedC();
BaseClass a1= c2; //BaseClass   ,DerivedC    BaseClass   
a1.play(); //play() BaseClass,DerivedC     ,         

分析:
1、なぜサブクラスのタイプのオブジェクトのインスタンスは、スーパークラスの参照に上書きされますか?
自動的にアップグレードを実現します。この文を通じて、コンパイラは自動的にサブクラスのインスタンスを上に移動し、汎用タイプのBaseClassになります。
2、a.play()は、サブクラスまたは親定義の方法を実行しますか?
サブクラスです。実行中は、aというオブジェクトから実際のタイプを引用して対応する方法を取得します。だから多形性があります。基本クラスのオブジェクト参照は、異なるサブクラスのオブジェクト参照を与えられ、この方法を実行すると、異なる挙動を示します。
a 1=c 2の時、依然として二つのハンドルが存在します。a 1とc 2ですが、a 1とc 2は同じブロックのデータメモリブロックと異なる関数テーブルを持っています。
2、親のオブジェクトをサブクラスのオブジェクトに参照して変数を参照することはできません。

BaseClass a2=new BaseClass();
DerivedC c1=a2;//  

javaの中で、上への転換は自動的に行われますが、下への転換はそうではなく、自分で定義して強制的に行う必要があります。c1=(DerivedC)a2;は強制転化を行い、つまり下方向へ転換する。
3、簡単で複雑な規則を覚えてください。一つのタイプの引用は、タイプ自体が含む方法と変数だけを参照してください。
この規則は間違っていると言えるかもしれません。親がサブクラスのオブジェクトを参照する時、最後に実行するのはサブクラスの方法です。
実はこれは矛盾していません。後期バインディングを採用して、動態的に運行する時にまた型別によってサブクラスの方法を呼び出しました。このサブタイプの方法が親に定義されていないと、エラーが発生します。
例えば、DerivedC類はBaseClassに定義された関数を継承する以外に、いくつかの関数(例えばmyFun()を追加しました。
分析:
親の参照を使用すると、実はjvmはコンパイラで生成されたタイプの情報を使って変換されました。
ここでは、親の類ではない関数を仮想函数表から不可視に設定することに相当するということが理解できます。なお、仮想函数表の関数アドレスの一部は、サブクラスで書き換えられているので、オブジェクト仮想函数表の仮想関数項目アドレスは、サブクラスで完了したメソッドのアドレスに設定されている。
4、JavaとC++多形性の比較
jvmの多形サポート解決方法は、c+++とほぼ同じです。ただし、c++のコンパイラの多くは、タイプ情報と仮想関数情報を一つの仮想関数テーブルに置いていますが、ある技術を利用して区別します。
Javaはタイプ情報と関数情報を分けてオープンします。Javaでは継承後、サブクラスは自分の仮想関数テーブルを再設定します。この仮想函数表の項目は二つの部分から構成されています。親から受け継いだ仮想関数と、サブ自身の仮想関数。
仮想関数呼び出しは仮想関数テーブルを介して間接的に呼び出されるので、多状態を実現することができます。Javaのすべての関数は、finalとして宣言されているものを除いて、後期に結合されています。
四.1つの行為、異なる対象、具体的に表す方式は違っています。
例えば、方法はoverloadingを再ロードし、方法はoverrideを書き換える(上書きする)。

class Human{
void run(){      }
}
class Man extends Human{
void run(){       }
}

この時、同じ走りでも、違う相手でも違います。

class Test{
void out(String str){   str}
void out(int i){   i}
}

この例は方法です。方法名は同じです。パラメータテーブルは違います。
これらが足りないことが分かりました。人を使って走ってみます。

Human ahuman=new Man();

このように私はManのオブジェクトを実用化し、Humanの引用を宣言して、Manのオブジェクトを指します。
Manという対象をHumanとして見たという意味です。
動物園に行ったら、動物を見ましたが、これは何ですか?これはパンダです
この2つの言葉は、パンダとは知らないが、親が動物であることを知っているので、このパンダの対象として、親の動物として見てもいいです。このような方法ではnew Man();に注意してください。ahuman.run()この方法で出力されたのは「男性が走っている」というものです。サブタイプのManにeat()のような独自の方法を書いています。Humanはこの方法がないので、eatメソッドを呼び出す時には、強制タイプ変換に注意しなければなりません。
インターフェースにとって、状況は似ています。

package domatic;
//    superA
class superA {
int i = 100;
void fun(int j) {
j = i;
System.out.println("This is superA");
}
}
//   superA   subB
class subB extends superA {
int m = 1;
void fun(int aa) {
System.out.println("This is subB");
}
}
//   superA   subC
class subC extends superA {
int n = 1;
void fun(int cc) {
System.out.println("This is subC");
}
}
class Test {
public static void main(String[] args) {
superA a = new superA();
subB b = new subB();
subC c = new subC();
a = b;
a.fun(100);
a = c;
a.fun(200);
}
}


/*
*      subB subC   superA   ,    Test    3     a, b,
* c,                              。      :
* “   (1) (2)   :This is superA” 。
* java           :                ,
*                              ,
*                      ,
*              。
*   ,      (1) (2)   ,    a.fun(),    (1)  a b  ,
*      subB     ,  (1)    fun()      subB     fun(),
*       superA     fun();  (2)      subC     fun() 。
*   ,               ,         new      ,
*                     ,          。           。
*   ,                       ,
*        abstract     ,           
*/

以上の大部分は子供種で親類をカバーする方法で多形を実現します。次はもう一つの多形を実現する方法です。――Cは父類を書き換える方法です。
1.JAVAには相続が多くなく、一つの種類の父があります。継承の表現は多状態です。一つの親は複数のサブクラスがありますが、サブクラスでは父親タイプの方法(例えば方法print)を書き換えることができます。このように、各サブクラスで書き換えられたコードは違っています。自然な表現形式は違います。このように親の変数で異なるサブクラスを引用すると、この同じ方法printを呼び出した時に得られた結果と表現の形式が違ってきます。これは多状態であり、同じメッセージ(つまり同じ方法を呼び出す)は違った結果になります。例を挙げて説明します

//  
public class Father{
//          
public void hitChild(){
}
}
//  1
public class Son1 extends Father{
//         
public void hitChild(){
System.out.println("     ?      !");
}
}
//  2
public class Son2 extends Father{
//         
public void hitChild(){
System.out.println("     ,   !");
}
}
//  3
public class Son3 extends Father{
//         
public void hitChild(){
System.out.println("  ,    !");
}
}
//   
public class Test{
public static void main(String args[]){
Father father;
father = new Son1();
father.hitChild();
father = new Son2();
father.hitChild();
father = new Son3();
father.hitChild();
}
}

同じ方法を使って、違う結果が出ました。これは多态の表现です。
もっと多くのjava関連の内容に興味がある読者は当駅のテーマを調べてもいいです。「Javaは対象プログラムに向かって入門と階段教程を設計します。」、「Javaデータ構造とアルゴリズム教程」、「Java操作DOMノード技術のまとめ」、「Javaファイルとディレクトリの操作テクニックのまとめ」、「Javaキャッシュ操作テクニックのまとめ
本論文で述べたように、皆さんのjavaプログラムの設計に役に立ちます。