継承によるメソッドの置き換え
次に継承によるメソッドの置き換えについてC#と比較してみましょう。
C#では、子クラスにて親クラスにあるメソッドと同じ名前のメソッドを作成し置き換えるには、newキーワードを使用します。しかし、newキーワードを使用した子クラスのメソッドは親クラス型オブジェクト経由で呼び出された場合には置き換えられず、親クラスのメソッドを呼んでしまいます。これを強制的に子クラスのメソッドに置き換えるためには、C#では、”virtual”と”override”キーワードを使用します。以下の例では、testMethod1はnewで置き換えられているため、親クラス型のオブジェクト(a)経由で呼び出された場合、置き換えられず、親クラスのメソッドを呼びますが、testMethod2は強制的に子クラスで実装されたメソッドに置き換えられます。
class testBaseClass1 //親クラス
{
public void testMethod1() { Console.WriteLine("ベース機能"); }
public virtual void testMethod2() { Console.WriteLine("ベース機能バーチャル"); }
}
class testChildClass1 : testBaseClass1 //testBaseClass1を継承
{
public new void testMethod1() { Console.WriteLine("子機能new"); }
// virtual + overrideキーワードでtestMethod2のみ完全に置き換えらる
public override void testMethod2() { Console.WriteLine("子機能override"); }
}
class Test
{
static void Main()
{
testBaseClass1 a = new testChildClass1();
testChildClass1 b = new testChildClass1();
//親クラスオブジェクトへの参照経由で呼び出すと置き換えられていない。
a.testMethod1();
b.testMethod1();
//親オブジェクトへの参照経由で呼び出しても、置き換えられている。
a.testMethod2();
b.testMethod2();
}
}
▼
ベース機能 子機能new 子機能override 子機能override
同様のテストをF#でしてみましょう。testBaseClass1とそれを継承しているtestChildClass1は2つの同名のメソッドを持ちますが、メソッドの上書きの強制度が異なります。testMethod1を親クラスのオブジェクト(testObj1)経由で呼び出す場合には、親クラスで実装されたメソッドが呼ばれますが、”abstract member”と”override”キーワードで定義されたtestMethod2は子クラスで実装されたメソッドが置き換えられて呼び出されます。”abstract member“で宣言されたメンバーは抽象メンバーですが、”default”とセットで使用し親クラスにてデフォルトの実装を定義することで、他.NET言語のvirtualのように機能します。
open System
type testBaseClass1() = //親クラス
member this.testMethod1() =
Console.WriteLine("testBaseClass1のtestMethod1")
abstract member testMethod2 : unit -> unit //抽象メソッド
default this.testMethod2() = //抽象メソッドのデフォルト実装
Console.WriteLine("testBaseClass1のtestMethod2")
type testChildClass1() =
inherit testBaseClass1() //testBaseClass1を継承
member public this.testMethod1() =
Console.WriteLine("testChildClass1のtestMethod1")
// "abstract member " + "override "がdefault実装を強制的に置き換える
override this.testMethod2() =
Console.WriteLine("testChildClass1のtestMethod2")
let mutable testObj1 = new testBaseClass1() //mutableで可変オブジェクト
let testObj2 = new testChildClass1()
testObj1 <- testObj2;;
testObj1.testMethod1();;//親クラス型への参照経由でもメソッドは置き換えられないはず
testObj2.testMethod1();;
testObj1.testMethod2();;//親クラス型への参照経由でもメソッドは置き換えられているはず
testObj2.testMethod2();;
▼
testBaseClass1のtestMethod1 val it : unit = () > testChildClass1のtestMethod1 val it : unit = () > testChildClass1のtestMethod2 val it : unit = () > testChildClass1のtestMethod2 val it : unit = ()
- 修正履歴
-
- 2010/01/25 22:02 読者コメント指摘により、一部表現を訂正。
この記事は参考になりましたか?
- C#プログラマのためのF#入門連載記事一覧
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
WINGSプロジェクト 星山 仁美(ホシヤマ ヒトミ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
