オーバーライド

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動先: 案内検索

オブジェクト指向プログラミングにおいてオーバーライド (override)とは、スーパークラスで定義されたメソッドサブクラスで定義しなおし、動作を上書きすることである。

あるクラスBaseにメソッドprintがあり、あるクラスDerivedがクラスBase継承したとする。そのとき、クラスDerivedはクラスBaseにあるメソッドprintをオーバーライドすることにより、再定義することができる。これはオブジェクト指向プログラミングにおけるポリモーフィズムを実現する際によく使われる。 オーバーライドを可能とする条件として、引数の型と数が統一されている必要がある。

メソッドのオーバーロード多重定義overload)と混同されることがあるが、まったく異なる概念である。 ※Rubyのようにオーバーロードの概念がなく、引数の型や数の条件がなくメソッド名が同一なだけでオーバーライドが成立する言語もある。

Java言語によるオーバーライドの例[編集]

class Base
  {
  // コンストラクター
  Base ()
    {System.out .println ("Base: Base") ;}

  // インスタンスメソッド
  void print ()
    {System.out .println ("Base: print") ;}

  // クラスメソッド
  static void staticPrint()
    {System.out .println ("Base: staticPrint") ;}
  }

class Derived extends Base
  {
  // コンストラクター
  Derived ()
    {System.out .println ("Derived: Derived") ;}

  // スーパークラス の インスタンスメソッド print をオーバーライドしている。
  void print ()
    {System.out .println ("Derived: print") ;}

  // スーパークラス の クラスメソッド staticPrint をオーバーライドすることはできない。
  static void staticPrint ()
    {System.out .println ("Derived: staticPrint") ;}
  }

このクラスを実行するプログラムを

public class Main
  {
  public static void main (String [] args)
    {
    System.out .println ("■インスタンスのメソッドを呼び出し (Baseインスタンス)") ;
    Base base = new Base () ;
    base .print () ;

    System.out .println ("■インスタンスのメソッドを呼び出し (Derivedインスタンス)") ;
    Derived derived = new Derived () ;
    derived .print () ;

    System.out .println ("■インスタンスのメソッドを呼び出し (Base型変数中のDerivedインスタンス)") ;
    Base derivedInBaseVariable = new Derived () ;
    derivedInBaseVariable .print () ;

    System.out .println ("■クラスメソッドを実行 (Base)") ;
    Base.staticPrint () ;

    System.out .println ("■クラスメソッドを実行 (Derived)") ;
    Derived.staticPrint () ;
    }
  }

として実行すると

■インスタンスのメソッドを呼び出し (Baseインスタンス)
Base: Base
Base: print
■インスタンスのメソッドを呼び出し (Derivedインスタンス)
Base: Base
Derived: Derived
Derived: print
■インスタンスのメソッドを呼び出し (Base型変数中のDerivedインスタンス)
Base: Base
Derived: Derived
Derived: print       //オーバライド
■クラスメソッドを実行 (Base)
Base: staticPrint
■クラスメソッドを実行 (Derived)
Derived: staticPrint

という結果が得られる。

その他の言語の例[編集]

C#[編集]

C#のオーバーライドの特徴として、以下が挙げられる。

  • 仮想メソッド、抽象メソッドのオーバーライドの際にoverrideキーワードの指定が必要である。
    但し、インターフェイスのメソッドを実装する場合は、overrideの指定は不要(不可)である。
  • メソッドは既定では非仮想であり、virtualを指定することでオーバーライド可能な仮想メソッドとなる。
  • プロパティインデクサ、イベントもメソッドと同様にオーバーライドの対象となる。

コードの例を示す。

abstract class Base {
    // 既定では非仮想メソッド
    public void GoodMorning() => Console.WriteLine("GoodMorning, Base!");

    // virtualを指定することで仮想メソッドとなる
    public virtual void Hello() => Console.WriteLine("Hello, Base!");

    public virtual void Goodbye() => Console.WriteLine("Goodbye, Base!");

    // 抽象メソッド
    public abstract void GoodNight();

}

class Derived : Base {
    // 非仮想メソッドはオーバーライドできない
    // 同名のメソッドで隠蔽する場合、newを指定する
    // (ここでは指定しないが、virtualを指定することで仮想メソッドとなる)
    public new void GoodMorning() => Console.WriteLine("GoodMorning, Derived!");

    // 仮想メソッドをオーバーライドする
    // overrideの指定が必須
    public override void Hello() => Console.WriteLine("Hello, Derived!");

    // 仮想メソッドをオーバーライドする
    // overrideと共にsealedを指定することで、
    // このクラスを継承した先ではオーバーライド禁止(非仮想)として扱われる
    public override sealed void Goodbye() => Console.WriteLine("Goodbye, Derived!");
    // 抽象メソッドをオーバーライドする

    // overrideの指定が必須
    public override void GoodNight() => Console.WriteLine("Good Night, Derived!");
}

class DerivedDerived : Derived {
    // 非仮想メソッドはオーバーライド不可
    //public override void GoodMorning() => Console.WriteLine("GoodMorning, DerivedDerived!");

    public override void Hello() => Console.WriteLine("Hello, DerivedDerived!");

    // sealedされたメソッドはオーバーライド不可
    //public override void Goodbye() => Console.WriteLine("Goodbye, DerivedDerived!");

    public override void GoodNight() => Console.WriteLine("Good Night, DerivedDerived!");
}

関連項目[編集]