サーチ…


前書き

ダイナミックメソッドディスパッチとは何ですか?

動的メソッドディスパッチは、オーバーライドされたメソッドへの呼び出しがコンパイル時ではなく実行時に解決されるプロセスです。オーバーライドされたメソッドが参照によって呼び出されると、Javaは参照するオブジェクトの型に基づいて実行するメソッドのバージョンを決定します。これは、ランタイムポリモーフィズムとしても知られています。

これを例を用いて見ていきます。

備考

  • 動的バインディング=遅延バインディング
  • 抽象クラスはインスタンス化できませんが、サブクラス化することができます(子クラスの場合はBase)
  • 抽象メソッドは、実装なしで宣言されるメソッドです
  • 抽象クラスには、実装の有無にかかわらず宣言されたメソッドが混在することがあります
  • 抽象クラスがサブクラス化されている場合、サブクラスは通常、その親クラスのすべての抽象メソッドの実装を提供します。しかし、そうでなければ、そのサブクラスもabstractと宣言しなければならない
  • 動的メソッドディスパッチは、オーバーライドされたメソッドへの呼び出しを実行時に解決するメカニズムです。これは、javaがランタイムポリモーフィズムを実装する方法です。
  • アップキャスティング(Upcasting):サブタイプをスーパータイプにキャスティングし、継承ツリーまで上向きにします。
  • ランタイム多態性=動的多型

動的メソッドディスパッチ - サンプルコード

抽象クラス:

package base;

/*
Abstract classes cannot be instantiated, but they can be subclassed
*/
public abstract class ClsVirusScanner {

    //With One Abstract method
    public abstract void fnStartScan();
    
    protected void fnCheckForUpdateVersion(){
        System.out.println("Perform Virus Scanner Version Check");
    }
    
    protected void fnBootTimeScan(){
        System.out.println("Perform BootTime Scan");
    }
    protected void fnInternetSecutiry(){
        System.out.println("Scan for Internet Security");
    }
    
    protected void fnRealTimeScan(){
        System.out.println("Perform RealTime Scan");
    }
    
    protected void fnVirusMalwareScan(){
        System.out.println("Detect Virus & Malware");
    }    
}

子クラスの抽象メソッドのオーバーライド:

import base.ClsVirusScanner;

//All the 3 child classes inherits the base class ClsVirusScanner
//Child Class 1
class ClsPaidVersion extends ClsVirusScanner{
    @Override
    public void fnStartScan() {
        super.fnCheckForUpdateVersion();
        super.fnBootTimeScan();
        super.fnInternetSecutiry();
        super.fnRealTimeScan();
        super.fnVirusMalwareScan();
    }
};    //ClsPaidVersion IS-A ClsVirusScanner
//Child Class 2

class ClsTrialVersion extends ClsVirusScanner{
    @Override
    public void fnStartScan() {
        super.fnInternetSecutiry();
        super.fnVirusMalwareScan();
    }
};    //ClsTrialVersion IS-A ClsVirusScanner

//Child Class 3
class ClsFreeVersion extends ClsVirusScanner{
    @Override
    public void fnStartScan() {
        super.fnVirusMalwareScan();
    }
};     //ClsTrialVersion IS-A ClsVirusScanner 

ダイナミック/レイトバインディングは、動的メソッドディスパッチにつながります。

//Calling Class
public class ClsRunTheApplication {

    public static void main(String[] args) {

        final String VIRUS_SCANNER_VERSION = "TRIAL_VERSION";

        //Parent Refers Null
        ClsVirusScanner objVS=null; 

        //String Cases Supported from Java SE 7
        switch (VIRUS_SCANNER_VERSION){
        case "FREE_VERSION":

            //Parent Refers Child Object 3
            //ClsFreeVersion IS-A ClsVirusScanner
            objVS = new ClsFreeVersion(); //Dynamic or Runtime Binding
            break;
        case "PAID_VERSION":

            //Parent Refers Child Object 1
            //ClsPaidVersion IS-A ClsVirusScanner
            objVS = new ClsPaidVersion(); //Dynamic or Runtime Binding
            break;
        case "TRIAL_VERSION":

            //Parent Refers Child Object 2
            objVS = new ClsTrialVersion(); //Dynamic or Runtime Binding
            break;
        }

        //Method fnStartScan() is the Version of ClsTrialVersion()
        objVS.fnStartScan();

    }
}

結果:

Scan for Internet Security  
Detect Virus & Malware

アップキャスティング:

objVS = new ClsFreeVersion();
objVS = new ClsPaidVersion();
objVS = new ClsTrialVersion()


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow