C Sharpの基礎 - 抽象クラス

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

抽象クラスとは、インスタンスを生成できないクラスのことで、継承することを前提としたクラスのことである。

抽象メソッドとは、実装を持たず、メソッドの意味(規約)のみを定義したメソッドである。
抽象メソッドの実装は、基底クラスでは行わず、派生クラスに記述する。

以下に、抽象クラス・抽象メソッドの特徴を示す。

  • クラスやメソッドの修飾子として、abstract修飾子を付加する。
  • 抽象メソッドは、基底クラスではメソッドの意味(規約)のみを定義して、派生クラスで具体的な実装を記述するメソッド。
    (C++において、純粋仮想関数と呼ばれるもの)
  • 抽象メソッドを1つでも持つクラス(抽象クラス)は、インスタンスを生成することができない。



抽象化

C#には、インスタンスを生成できないクラスや実装の無いメソッド(派生クラスでオーバーライドする)を定義するための構文が存在する。
インスタンスを生成できないクラスは、抽象クラスと呼ばれる。

抽象クラスを作成するには、クラスの定義時にabstract修飾子を付加する。

 abstract class Person
 {
    protected int age;
 
    // 抽象クラスなので、コンストラクタが public であってもインスタンスは生成できない。
    public Person(int age)
    {
       this.age  = age;
    }
 
    public virtual int Age
    {
       get => 0;
    }
 }


意味(規約)のみを定義して、実装は派生クラスに記述するメソッドは、抽象メソッドと呼ばれる。
抽象メソッドを作成するには、メソッドにabstract修飾子を付加する。なお、抽象メソッドは抽象クラスのみ定義できる。
また、抽象プロパティを作成するには、abstract修飾子を付加する。

 abstract class Person
 {
    protected int age;
 
    public Person(int age)
    {
       this.age = age;
    }
 
    public abstract int Age
    {
       get;  // 抽象プロパティに定義は不要
    }
 }


以下の例では、抽象クラスを定義している。

 using System;
 
 // 抽象クラス
 abstract class Person
 {
    protected string name;
    protected int age;
 
    public Person(string name, int age)
    {
       this.name = name;
       this.age  = age;
    }
 
    public string Name
    {
       get => this.name;
    }
 
    public abstract int Age
    {
       get;  // 抽象プロパティに定義は不要
    }
 }
 
 /// <summary>
 /// </summary>
 class Truepenny : Person
 {
    public Truepenny(string name, int age) : base(name, age)
    {
    }
 
    public override int Age
    {  // 実年齢を返す
       get => return this.age;
    }
 }
 
 /// <summary>
 /// </summary>
 class Liar : Person
 {
    public Liar(string name, int age) : base(name, age)
    {
    }
 
    public override int Age
    {
       get
       {  // サバを読んだ年齢を返す
          if(this.age < 20) return this.age;
          if(this.age < 25) return this.age - 1;
          if(this.age < 30) return this.age - 2;
          if(this.age < 35) return this.age - 3;
          if(this.age < 40) return this.age - 4;
 
          return this.age - 5;
       }
    }
 }
 
 /// <summary>
 /// </summary>
 class Equivocator : Person
 {
    public Equivocator(string name, int age) : base(name, age)
    {
    }
 
    public override int Age
    {  // 年齢を四捨五入した値を返す
       get => ((this.age + 5) / 10) * 10;
    }
 }
 
 class Sample
 {
    static void Main()
    {
       Introduce(new Truepenny  ("hoge", 24));
       Introduce(new Liar       ("piyo", 24));
       Introduce(new Equivocator("fuga", 24));
    }

    /// <summary>
    /// </summary>
    static void Introduce(Person p)
    {
       Console.Write("My name is {0}.\n", p.Name);
       Console.Write("I'm {0} years old.\n\n", p.Age);
    }
 }


# 出力
My name is hoge.
I'm 24 years old.

My name is piyo.
I'm 23 years old.

My name is fuga.
I'm 20 years old.