本連載では、C#で「最低限」なんらかのコードを書いたことのあるプログラマーを対象に、関数型プログラミング言語「F#」について数回にわたり解説していきます。第3回目は、F#におけるオブジェクト指向の基本機能について紹介します。
はじめに
「C#プログラマのためのF#入門」第3回目は、F#におけるオブジェクト指向の基本機能について紹介します。
.NETの基本クラスライブラリは、オブジェクト指向風に作成されているため、既存のクラス構造との互換性のためにも、オブジェクト指向のテクニックはF#において欠かせません。
F#は、C#同様に下記のようなオブジェクト指向の基本機能をサポートします。
- クラスは単一クラスのみ継承できる
- クラスは複数のインターフェイスを継承できる
- すべてのオブジェクトは共通のベースクラスとしてSystem.Object(エイリアス:obj)を持つ
加えて、F#固有の機能としては次のようなものが挙げられます。
- メソッドだけではなくプロパティやイベントの拡張が可能
- オブジェクト式(Object Expression)
- ミュータブル、イミュータブルなオブジェクト
これらのF#固有の機能を説明するにあたり、まずは、F#のオブジェクト指向基本編として、今回はオブジェクト指向の基本単位とも言える「クラス」の構造について解説したいと思います。
1. クラス
F#においても、クラスはオブジェクト指向の基本単位と言えます。クラスの定義方法、機能は大変C#のものに似ています。クラスでは、オブジェクトが使用できるフィールド、プロパティ、メソッド、イベントを宣言します。
2-1.クラスの作成
クラスを作成する際の基本構文は次のようになります。
type [アクセス修飾子] クラス名[<ジェネリックパラメータ>](コンストラクタのパラメータ(リスト)) [as セルフ識別子] =
[class]
[inherit ベースとなるクラスの名前(ベースコンストラクタ引数)]
[letバインド]
[do-バインド]
メンバーリスト
…
[end]
(1)type キーワード
F#ではtypeキーワードを用いて、通常のクラスだけではなく抽象クラス、インターフェイス、部分的なフィールドの実装を持つクラスなど数種類のオブジェクトタイプを作成できますが、明示的にこれらを指定する必要はありません。F#のコンパイラはフィールドが宣言されている、あるいはmemberが(宣言ではなく)実装されている場合、typeキーワードで宣言しているオブジェクトをインターフェイスではなくクラスと判断します。クラス内に宣言のみされ実装されていないメンバーがある場合、クラスは抽象クラスとみなされます。
上記の構文には、角カッコを使用していろいろオプショナルなアイテムが記述されていますが、最もシンプルなクラスは次のように定義できます。
type testClass1 =
class
end ;;
このままでは、このクラスは何の役にも立たず、インスタンスを作成することができませんので、次にコンストラクタを追加してみましょう。
(2)プライマリコンストラクタ
他の.NET言語とは異なり、F#ではプライマリコンストラクタと呼ばれるコンストラクタが1つ存在します。プライマリコンストラクタはクラス名の後ろに丸カッコをつけ、その中にパラメータを指定することで作成できます。
では、最も単純なプライマリコンストラクタを持つクラスのインスタンスを作成してみましょう。
let インスタンス名 = new クラス名(コンストラクタ用パラメータ)
ここで言う最も単純なプライマリコンストラクタとは、引数を受け付けず、また初期化プログラムが一切存在しないコンストラクタのことです。
type testClass1() =
class
end;;
//インスタンス作成
let testObj1 = new testClass1();;
▼
type testClass1 =
class
new : unit -> testClass1 //unit型のパラメータを受け取り(つまりデータを受け取らない)、testClass1型のオブジェクトを作成するコンストラクタを表す。
end
val testObj1 : testClass1 //testClass1型のインスタンスtestobj1が作成された。
プライマリコンストラクタはletバインド(束縛)でフィールドを宣言し、続くdo式ですべてのインスタンスの初期化プログラム(コード)を実行します。
下記のリスト3ではプライマリコンストラクタはint型のパラメータを2つ受け取り、ミュータブル変数aとbを初期化し、それらをprintfで表示させます。
ミュータブル変数については連載の次回で詳しく解説しますが、今回は「mutableというキーワードがフィールドをミュータブル(可変)なフィールドにする」ということだけ覚えてください。
type testClass1(a1 : int, b1 : int) = //int型のパラメータを2つ受け取る。
let a = a1 + b1 //フィールドの定義(束縛)
let mutable b = a1 * b1 //フィールドの定義(束縛)
do printf "%d, %d" a b ;; //初期化処理
▼
type testClass1 =
class
new : a1:int * b1:int -> testClass1 //a1(int型)とb1(int型)のパラメータを受け取り、testClass1型のオブジェクトを作成するコンストラクタを表す。
end
インスタンスを作成してみましょう。
let testObj1 = new testClass1(10, 20) ;; //2つのint型のパラメータを渡してtestClass1型のインスタンスを作成する。
▼
30, 200 //初期化処理が行われた val testObj1 : testClass1 //インスタンスが作成された
この記事は参考になりましたか?
- 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
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
