Java静的結合と動的結合
最近、私はJavaの知識を学び、Javaの静的および動的な結合を学びました。次に、知識のこの部分を習得するために、Baiduに関する対応する知識を要約して整理しました。
プログラムバインディングの概念:
バインディングとは、メソッドが配置されているクラス(メソッド本体)とメソッドコールとの関連付けを指します。 Javaの場合、結合は静的結合と動的結合に分割されます。または、それは早期結合と遅い結合と呼ばれます。
静的結合:
このメソッドは、プログラムが実行される前にバインドされています(つまり、このメソッドがコンパイルプロセスにあるクラスが既にわかっています)、コンパイラまたは他の接続プログラムによって実装されます。例:C。
Javaのプログラム編集期間中に拘束力があるだけであると理解できます。 Javaの唯一の方法は、事前拘束力のある最終、静的、プライベート、およびコンストラクターであることが特に明らかです。
動的バインディング:
後で結合:実行時に特定のオブジェクトのタイプに応じてバインドします。
言語が遅い結合を実装する場合、操作中にオブジェクトのタイプを決定し、適切な方法を個別に呼び出すためのいくつかのメカニズムも提供する必要があります。言い換えれば、コンパイラはまだ現時点ではオブジェクトタイプを知りませんが、メソッド呼び出しメカニズムはそれを単独で調査し、正しいメソッド本体を見つけることができます。言語が異なると、遅延バインディングを実装する方法が異なります。しかし、少なくともこのように考えることはできます。それらはすべて、オブジェクトに特定の特別な種類の情報をインストールする必要があります。
動的結合プロセス:
最終的、静的、プライベート、コンストラクターは、早期の拘束力を理解しています
プライベートな方法では、まず第一に、継承することはできません。継承することはできないため、サブクラスのオブジェクトを介してそれを呼び出す方法はありませんが、このクラス自体のオブジェクトを介してのみ呼び出すことができます。したがって、プライベート方法は、この方法を定義するクラスにバインドされていると言えます。
最終的な方法は継承できますが、上書きすることはできません(上書き)。子クラスのオブジェクトは呼び出すことができますが、親クラスで定義されている最終的な方法は呼び出されます(これから、この方法は最終タイプとして宣言され、1つはメソッドが上書きされないようにし、もう1つはJavaでの動的結合を効果的に閉じることです)。
コンストラクターを継承することはできません(サブクラスは親クラスのパラメーターレスコンストラクターをコンストラクターとして無条件に継承していると言っていますが、個人的には、この声明は不適切だと思います。サブクラスは、親クラスの初期化を完了するために親クラスを完了するために、親クラスを使用する必要はないので、サブクラスは親クラスの初期化を完了する必要はありません。コンストラクター)。したがって、コンパイル時にこのコンストラクターが属するクラスを知ることもできます。
静的メソッドの特定の原則をよく説明することはできません。ただし、オンライン情報と私自身の実験に基づいて、静的方法はサブクラスで継承できるが、サブクラスで書き換える(オーバーライド)できないが、サブクラスで隠すことはできないと結論付けることができます。 (これは、親クラスに静的な方法があり、サブクラスに対応する方法がない場合、子クラスのオブジェクトがこの方法を呼び出すときに親クラスのメソッドが使用されることを意味します。また、子クラスで定義されたメソッドが定義されている場合、子供クラスのオブジェクトがstatic fight intic aseic ase in firt a static classオブジェクトに変換された場合、子クラスのクラスは子どものクラスに変換される場合、子どものクラスで定義された方法が呼び出されます。したがって、子のクラスは、静的な方法を隠すことはできないと言われていますが、子クラスの違いは、親クラスの違いに変換された後、親クラスの違いにアクセスできます。
上記から、メソッドを継承できない場合、または継承後に上書きできない場合、このメソッドは静的結合を採用すると結論付けることができます。
Javaの編集と操作
Javaコンパイルプロセスは、JavaソースファイルをByteCode(JVM実行可能性コード、つまり.Classファイル)にコンパイルするプロセスです。このプロセスでは、Javaはメモリに対処しません。このプロセスでは、コンパイラは構文分析を実行します。構文が正しくない場合、エラーが報告されます。
Java実行プロセスとは、Bytecodeファイルの読み込みと実行の解釈JVM(Java Virtual Machine)を指します。このプロセスでは、それはJavaプログラムのメモリレイアウトと実行の実際の作成です。
Java Bytecodeを実行するには2つの方法があります。(1)インスタントコンパイル方法:インタープリターは最初にバイトをマシンコードにコンパイルし、次にマシンコードを実行します。 (2)説明実行方法:インタープリターは、毎回小さなコードを解釈および実行することにより、Javaバイトコードプログラムのすべての操作を完了します。 (ここでは、Javaプログラムが実際に実行プロセス中に2つの変換を受けることがわかります。最初にバイトコードに変換され、次にマシンコードに変換されます。これが、Javaを一度にコンパイルして実行できる理由でもあります。
前述のように、Javaの方法については、初期のバインディングである最終、静的、プライベート、およびコンストラクターを除き、他のすべての方法は動的なバインディングです。
典型的な動的結合は、親クラスと子クラスの変換宣言の下で発生します。
例:親p = new Children();
特定のプロセスの詳細は次のとおりです。
1:コンパイラは、オブジェクトの宣言タイプとメソッド名をチェックします。
XF(args)メソッドを呼び出し、xがクラスCのオブジェクトとして宣言されているとし、コンパイラはクラスCのスーパークラスから継承されたクラスCおよびFメソッドのFという名前のすべてのメソッドをリストします。
2:次に、コンパイラはメソッド呼び出しで提供されるパラメータータイプをチェックします。
名前Fを使用してすべてのメソッドの1つのパラメータータイプが、コールが最も多く提供されているパラメータータイプと一致する場合、このメソッドは呼び出されます。このプロセスは「過負荷解像度」と呼ばれます。
3:プログラムが実行され、動的バインディングを使用してコールメソッドを使用する場合、仮想マシンは、xが指すオブジェクトの実際のタイプに一致するメソッドバージョンを呼び出す必要があります。
実際のタイプがd(cのサブクラス)、クラスDがf(string)を定義する場合、メソッドが呼び出されると仮定します。そうしないと、メソッドf(string)がdのスーパークラスで検索されるなどです。
Java仮想マシンがクラスメソッド(静的メソッド)を呼び出すと、オブジェクト参照のタイプ(通常はコンパイル時間で既知)に基づいて呼び出されたメソッドを選択します。それどころか、仮想マシンがインスタンスメソッドを呼び出すと、オブジェクトの実際のタイプ(実行時にのみ既知)に基づいて呼び出されたメソッドを選択します。これは動的な結合であり、これは一種の多型です。動的バインディングは、実際のビジネス上の問題を解決するための優れた柔軟性を提供し、非常に美しいメカニズムです。
メソッドとは異なり、Javaクラスでメンバー変数(インスタンス変数とクラス変数)を扱う場合、それはランタイム結合ではなく、一般的な意味での静的結合です。したがって、上向きの変換の場合、オブジェクトのメソッドはサブクラスを見つけることができ、オブジェクトの属性(メンバー変数)は引き続き親クラスの属性(親クラスメンバー変数からのサブクラスの隠し)です。
パブリッククラスの父{保護された文字列名= "父属性"; }パブリッククラスの息子は父親を拡張します{保護された文字列name = "son属性"; public static void main(string [] args){父サンプル= new Son(); system.out.println( "calk calk property:" + sample.name); }}結論:発信者は父親の属性です。
この結果は、子クラスのオブジェクト(親クラスの参照ハンドル)が親クラスのメンバー変数に呼び出されることを示しています。したがって、ランタイム(動的)バインディングによって標的とされるカテゴリがオブジェクトの方法のみであることは明らかです。
サブクラスメンバー変数名を呼び出そうとしていますが、それを行う方法は?最も簡単な方法は、メンバー変数をメソッドゲッターフォームにカプセル化することです。
コードは次のとおりです。
パブリッククラスの父{保護された文字列名= "父属性"; public string getName(){return name; }}パブリッククラスの息子は父親を拡張します{保護された文字列名= "son属性"; public string getName(){return name; } public static void main(string [] args){父サンプル= new Son(); system.out.println( "calk calk property:" + sample.getName()); }}結果:息子の属性が呼ばれます
なぜJavaは属性に静的結合法を採用するのですか?これは、静的バインディングには多くの利点があるためです。これにより、実行期間ではなく、コンピレーション期間中にプログラムのエラーを発見できるためです。これにより、プログラムの運用効率が向上します!方法の動的結合は、Javaの主要な特徴である多型を実装することです。多型は重要なオブジェクト指向のテクノロジーの1つでもあるため、Javaが効率を犠牲にして多型を実装することは価値があります。
注:上記のコンテンツのほとんどはインターネットからのものであり、小さな部分は個人的な意見であり、決して権威ある発言ではありません。不適切な言語や誤った表現がある場合は、アドバイスをお願いします。
読んでくれてありがとう、私はそれがあなたを助けることができることを願っています。このサイトへのご支援ありがとうございます!