コンストラクタ・静的クラス・抽象クラス・部分クラス (3/4)
作成:2013-08-17 10:48
更新:2013-08-17 10:48
更新:2013-08-17 10:48
■抽象クラス
いくつかのクラスを定義するとき、「それらのクラスに共通する機能」を実装したい、と考えたとしましょう。例えば、個人情報を管理するためのクラスを作るとします。「生徒」とか「社会人」とかいくつかのクラスを作成し、それらにフィールドとして個人情報を保管します。
このとき、すべてのクラスに「印刷する」というメソッドを用意したい、としましょう。どうすればよいでしょうか? ただ、1つ1つのクラスにメソッドをかけばいい、ということだと、書き忘れたり、メソッド名や引数などが微妙に違うものを作ってたりする危険もあります。「必ず、このメソッドがある!」というようにしたい、つまり「○○というメソッドがあることを保証したい」というときは?
まず、考えつくのは、「印刷する」メソッドを持ったクラスを用意し、これを継承してクラスを作る、といったやり方でしょう。このやり方ならば、スーパークラスにメソッドがありますから必ずメソッドが用意されますね。けれど、「それぞれのクラスに用意される」ことは保証されません。つまり、サブクラスにそれぞれメソッドがオーバーライドされているかわからないのです。生徒クラスにも社会人クラスにも、それぞれのクラスに保管されている個人情報をまとめて出力するメソッドが用意されているかどうかはわからないのです。
こうした、「それぞれのクラスに、必ず○○というメソッドが定義されていることを保証する」のに用いられるのが「抽象クラス」というものです。これは、「そのままでは使えないクラス」です。クラスをそのままnewすることのできないクラスなのです。ではどうするか?というと、抽象クラスを継承したクラスを作って利用するのです。つまり、「継承するサブクラスを作らないと使えない」ようになってるのですね。
●抽象クラスの定義
この抽象クラスには、「抽象メソッド」と呼ばれるものが用意されます。これはメソッドの実装部分がない(つまり、メソッドの後の{…}の部分がない)メソッドの宣言の部分だけのものです。実装部分がありませんから、このメソッドはもちろん使えません。どうするかというと、サブクラスでこのメソッドをオーバーライドして使うのです。
この抽象メソッドは、サブクラスで「必ずオーバーライドしなければいけない」という決まりになっています。つまり、「このメソッドは使わないからオーバーライドしなくていいや」というのは許されないのです。抽象クラスを継承したクラスでは、そこにある抽象メソッドを必ずすべてオーバーライドしないといけないんですね。
従って、抽象クラスと抽象メソッドという形で処理を用意し、これを継承してクラスを作れば、必ず「すべてのクラスに○○というメソッドが実装される」ということが保証されるわけです。
下のリスト欄に簡単なサンプルをあげておきます。ここではPerson抽象クラスを用意し、それを継承したStudentとEmployeeクラスを作って使っています。
このとき、すべてのクラスに「印刷する」というメソッドを用意したい、としましょう。どうすればよいでしょうか? ただ、1つ1つのクラスにメソッドをかけばいい、ということだと、書き忘れたり、メソッド名や引数などが微妙に違うものを作ってたりする危険もあります。「必ず、このメソッドがある!」というようにしたい、つまり「○○というメソッドがあることを保証したい」というときは?
まず、考えつくのは、「印刷する」メソッドを持ったクラスを用意し、これを継承してクラスを作る、といったやり方でしょう。このやり方ならば、スーパークラスにメソッドがありますから必ずメソッドが用意されますね。けれど、「それぞれのクラスに用意される」ことは保証されません。つまり、サブクラスにそれぞれメソッドがオーバーライドされているかわからないのです。生徒クラスにも社会人クラスにも、それぞれのクラスに保管されている個人情報をまとめて出力するメソッドが用意されているかどうかはわからないのです。
こうした、「それぞれのクラスに、必ず○○というメソッドが定義されていることを保証する」のに用いられるのが「抽象クラス」というものです。これは、「そのままでは使えないクラス」です。クラスをそのままnewすることのできないクラスなのです。ではどうするか?というと、抽象クラスを継承したクラスを作って利用するのです。つまり、「継承するサブクラスを作らないと使えない」ようになってるのですね。
●抽象クラスの定義
abstract class クラス
{
abstract メソッドの定義;
……略……
}
この抽象クラスには、「抽象メソッド」と呼ばれるものが用意されます。これはメソッドの実装部分がない(つまり、メソッドの後の{…}の部分がない)メソッドの宣言の部分だけのものです。実装部分がありませんから、このメソッドはもちろん使えません。どうするかというと、サブクラスでこのメソッドをオーバーライドして使うのです。
この抽象メソッドは、サブクラスで「必ずオーバーライドしなければいけない」という決まりになっています。つまり、「このメソッドは使わないからオーバーライドしなくていいや」というのは許されないのです。抽象クラスを継承したクラスでは、そこにある抽象メソッドを必ずすべてオーバーライドしないといけないんですね。
従って、抽象クラスと抽象メソッドという形で処理を用意し、これを継承してクラスを作れば、必ず「すべてのクラスに○○というメソッドが実装される」ということが保証されるわけです。
下のリスト欄に簡単なサンプルをあげておきます。ここではPerson抽象クラスを用意し、それを継承したStudentとEmployeeクラスを作って使っています。
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
using System; namespace myapp { class Program { public static void Main(string[] args) { Student p = new Student(); p.name = "tuyano"; p.grade = 2; p.printData(); Employee e = new Employee(); e.name = "hanako"; e.position = "president"; e.printData(); Console.ReadKey(); // キーを押すまで待つ } } abstract class Person { public abstract void printData(); } class Student : Person { public String name; public int grade; public override void printData() { Console.WriteLine("name:" + name + ", grade:" + grade + "."); } } class Employee : Person { public String name; public String position; public override void printData() { Console.WriteLine("Hi, my name is " +name + ". my position is " + position + "."); } } }
※関連コンテンツ