メソッドオーバーライド-Override


メソッドオーバーライドとは、子クラスで定義されたメソッドの1つで、その名前、戻りタイプおよびパラメータ署名が親クラスのメソッドの名前、戻りタイプおよびパラメータ署名とちょうど一致する場合、子クラスのメソッドが親クラスのメソッドをオーバーライドしていると言える.
メソッドのオーバーライドは、さまざまな制約を満たす必要があります.以下で説明します.
(1)サブクラスメソッドの名前、戻りタイプおよびパラメータ署名は、親メソッドの名前、戻りタイプおよびパラメータ署名と一致する必要があります.
例:次のコードはコンパイルエラーを引き起こします.
public class Base {
    public void method(){
        
    }
}

public class Sub extends Base {
    public int method(){//    ,       
        return 0;
    }
}

子クラスで親クラスのmethod()メソッドを上書きしてから再ロードすると、合法的になります.
public class Base {
    public void method(){
        
    }
}

public class Sub extends Base {
    
    public void method(){
        
    }
    public int method(int a){
        return 0;
    }

}

(2)サブクラスメソッドでは親メソッドへのアクセス権を縮小できません.
例:次のコードはコンパイルエラーを引き起こします.
public class Base {
    public void method(){
        
    }
}
public class Sub extends Base {
    
    private void method(){//    ,                
        
    }

}

エラー原因分析:
この制限がなければjavaマルチステートメカニズムと競合します.次のコードについて
Base base = new Sub();
base.method();

Javaコンパイラは,以上が正当コードであると考え,実行時に動的バインディングルールに従って,Java仮想機会がbase変数が参照するSubインスタンスのmethod()メソッドを呼び出し,このメソッドがprivateタイプであればJava仮想マシンはそれにアクセスできない.
(3)子は親よりも多くの異常を放出できません.子が放出する異常は親が放出する異常と同じか、子が放出する異常は親が放出する異常の子である必要があります.
(4)メソッドオーバーライドは、子と親(直接親と間接親を含む)の間にのみ存在します.同じクラスではメソッドはリロードのみでオーバーライドできません.
(5)親の静的メソッドは,クラスを非静的メソッドとして上書きすることはできない.
例:次のコードはコンパイルエラーを引き起こします.
public class Base {
    public static void method(){
        
    }
}

public class Sub extends Base {
    
    public void method(){ //    
        
    }

}

(6)サブクラスは、親の静的メソッドと同じ名前の静的メソッドを定義できます.ただし、メソッドの上書き制約条件であるメソッドのパラメータ署名が一致し、戻りタイプが一致し、親メソッドのアクセス権を縮小することができず、親メソッドよりも多くの例外を放出することはできません.
例:次のコードは正当です.
public class Base {
    static int method(int a) throws Exception{
        return 0;
    }

}

import java.io.IOException;

public class Sub extends Base {
    
    public static int method(int a) throws IOException{
        return 0;
    }

}

(7)親の非静的メソッドは,クラスを静的メソッドとして上書きすることはできない.
public class Base {
    public void method(){
        
    }
}

public class Sub extends Base {
    
    public static void method(){ //    
        
    }

}

(8)親のプライベートメソッドは,クラスに上書きされてはならない.
例:次のコード:
public class Base {
    private void say(){
        System.out.println("I am Base Class");
    }
    
    public void speak(){
        say();
    }
}
public class Sub extends Base {
    public void say(){
        System.out.println("I am Sub Class");
    }
    
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.speak();
    }

}

実行結果:
I am Base Class

ベースクラスのsay()メソッドをpublic型に変更すると、次のようになります.
private void say(){
        System.out.println("I am Base Class");
    }

では、実行結果は次のとおりです.
I am Sub Class

(9)親の抽象的な方法は,布団類を2つの方法で覆うことができる.
1)子の親を実現するための抽象的なアプローチ
2)サブクラスが親を再宣言する抽象メソッド
例:次のコードは合法的です.
public abstract class Base {
    public abstract void method1();
    public abstract void method2();

}
public abstract class Sub extends Base {
    public void method1(){
        
    }
    
    public abstract void method2();

}

(10)親の非抽象メソッドを抽象メソッドとして上書きすることができる
例:次のコードは合法的です.
public class Base {
    void method(){
        
    }

}
public abstract class Sub extends Base {
    public abstract void method();

}