この章では、オブジェクト指向の応用編の解説を行います。

「継承」、「派生クラスのオーバーライド」、「ポリモーフィズム」、「抽象クラス」、「インターフェイス」について解説します。
これらを理解することで実践的なプログラミングに応用することができるようになります。
「C#基礎講座」の第11章です。この講座の詳細については以下から確認できます。
全てのサンプルプログラムのダウンロードは0章でダウンロードできます。


継承とは?
継承は、既存のクラスの機能を継承し、新しいクラスを作成する手法です。「基底クラス」から「派生クラス」を作成することで、共通の機能を持つ複数のクラスを作成することができます。
class Shape {
public int Width { get; set; }
public int Height { get; set; }
//幅と高さを表示するメソッド
public void ShowDim() {
Console.WriteLine("Width : " + Width + " Height : " + Height);
}
}
class Rectangle : Shape {
//面積を表示するメソッド
public void ShowArea() {
Console.WriteLine("Area : " + (Width * Height));
}
}
このプログラムでは、Shapeクラスを基底クラスとして、Rectangleクラスを派生クラスとしています。Shapeクラスには、WidthとHeightのプロパティと、ShowDimメソッドが定義されています。Rectangleクラスは、Shapeクラスを継承しており、ShowDimメソッドを継承し、ShowAreaメソッドを新しく定義しています。
派生クラスとオーバーライド
派生クラスは、基底クラスの機能を継承しますが、必要に応じて機能を上書きすることができます。これを「メソッドのオーバーライド」と言います。オーバーライドすることで、基底クラスの機能を拡張したり、変更したりすることができます。
以下のプログラムでは、ShapeクラスのShowDimメソッドをvirtualキーワードを使用して、派生クラスで上書き可能にしています。Rectangleクラスは、Shapeクラスを継承し、ShowDimメソッドをoverrideキーワードを使用して上書きしています。
class Shape {
public int Width { get; set; }
public int Height { get; set; }
//幅と高さを表示するメソッド
public virtual void ShowDim() {
Console.WriteLine("Width : " + Width + " Height : " + Height);
}
}
class Rectangle : Shape {
//長方形の場合の幅と高さを表示するメソッド
public override void ShowDim() {
Console.WriteLine("Rectangle Width : " + Width + " Height : " + Height);
}
}
ポリモーフィズムについて
ポリモーフィズムは、異なるクラスのインスタンスを同じように扱うことができる機能です。基底クラスを経由して派生クラスのインスタンスを扱うことで、異なるクラスのインスタンスを同じインターフェイスで扱うことができます。
using System;
using System.Collections.Generic;
namespace Csharp_Course
{
class Shape
{
public int Width { get; set; }
public int Height { get; set; }
//幅と高さを表示するメソッド
public virtual void ShowDim()
{
Console.WriteLine("Width : " + Width + " Height : " + Height);
}
}
class Rectangle : Shape
{
//長方形の場合の幅と高さを表示するメソッド
public override void ShowDim()
{
Console.WriteLine("Rectangle Width : " + Width + " Height : " + Height);
}
}
class Circle : Shape
{
//円の場合の幅と高さを表示するメソッド
public override void ShowDim()
{
Console.WriteLine("Circle Width : " + Width + " Height : " + Height);
}
}
internal class Program
{
static void Main(string[] args)
{
//配列に長方形、円、Shapeを代入
Shape[] shapes = new Shape[3];
shapes[0] = new Rectangle();
shapes[0].Width = 5;
shapes[0].Height = 6;
shapes[1] = new Circle();
shapes[1].Width = 10;
shapes[1].Height = 10;
shapes[2] = new Shape();
shapes[2].Width = 1;
shapes[2].Height = 2;
//配列内のshapeをforeach文で一つずつ取り出し、それぞれのShowDimメソッドを呼び出す
foreach (Shape shape in shapes)
{
shape.ShowDim();
}
}
}
}
このプログラムでは、Shapeクラスを基底クラスとして、Rectangleクラス、Circleクラスを派生クラスとしています。基底クラスであるShapeクラスのShowDimメソッドは、virtualキーワードを使用して、派生クラスで上書き可能にしています。
そして、派生クラスであるRectangleクラス、CircleクラスはそれぞれShowDimメソッドをoverrideし、異なる内容を出力しています。そして、配列shapesに、Rectangleクラス、Circleクラス、Shapeクラスのインスタンスを代入し、foreach文を使用し、基底クラスShapeのShowDimメソッドを呼び出しています。
これによって、配列内に格納されている異なるクラスのインスタンスを同じインターフェイスで扱うことができる。
抽象クラスについて
抽象クラスは、インスタンスを生成することができないクラスで、派生クラスに共通の機能を提供するために使用されます。 抽象メソッドやプロパティを含む抽象クラスは、派生クラスに実装を強制します。
抽象クラスやメソッドを定義にするには、abstractキーワードを使用して定義します。
using System;
using System.Collections.Generic;
namespace Csharp_Course
{
abstract class Shape
{
public int Width { get; set; }
public int Height { get; set; }
//幅と高さを表示する抽象メソッド
public abstract void ShowDim();
}
class Rectangle : Shape
{
//長方形の場合の幅と高さを表示するメソッド
public override void ShowDim()
{
Console.WriteLine("Rectangle Width : " + Width + " Height : " + Height);
}
}
internal class Program
{
static void Main(string[] args)
{
//長方形のインスタンスの生成
Shape rectangle = new Rectangle();
rectangle.Width = 5;
rectangle.Height = 6;
rectangle.ShowDim();
}
}
}
このプログラムでは、Shapeクラスを抽象クラスとして、Rectangleクラスを派生クラスとしています。
Shapeクラスには、WidthとHeightのプロパティと、ShowDimメソッドが定義されていますが、ShowDimメソッドはabstractキーワードを使用して抽象メソッドとして定義しています。そして、Rectangleクラスは、Shapeクラスを継承し、ShowDimメソッドをoverrideキーワードを使用して上書きしています。
インターフェイスについて
インターフェイスは、クラスが実装するべきメソッドやプロパティを定義するためのものです。 インターフェイスを実装することで、複数のクラスが共通のインターフェイスを持つことができます。
インターフェイスを定義するには、Interfaceキーワードを使用して定義します。
using System;
using System.Collections.Generic;
namespace Csharp_Course
{
interface IShape
{
int Width { get; set; }
int Height { get; set; }
void ShowDim();
}
class Rectangle : IShape
{
public int Width { get; set; }
public int Height { get; set; }
//長方形の場合の幅と高さを表示するメソッド
public void ShowDim()
{
Console.WriteLine("Rectangle Width : " + Width + " Height : " + Height);
}
}
class Circle : IShape
{
public int Width { get; set; }
public int Height { get; set; }
//円の場合の幅と高さを表示するメソッド
public void ShowDim()
{
Console.WriteLine("Circle Width : " + Width + " Height : " + Height);
}
}
internal class Program
{
static void Main(string[] args)
{
//配列に長方形、円を代入
IShape[] shapes = new IShape[2];
shapes[0] = new Rectangle();
shapes[1] = new Circle();
//配列内のshapeをforeach文で一つずつ取り出し、それぞれのShowDimメソッドを呼び出す
foreach (IShape shape in shapes)
{
shape.ShowDim();
}
}
}
}
このプログラムでは、IShapeインターフェイスを定義し、Widthプロパティ、Heightプロパティ、ShowDimメソッドを定義しています。そして、Rectangleクラス、CircleクラスはそれぞれIShapeインターフェイスを実装しています。
そして、配列shapesに、Rectangleクラス、Circleクラスのインスタンスを代入し、foreach文を使用し、IShapeインターフェイスのShowDimメソッドを呼び出しています。これによって、配列内に格納されている異なるクラスのインスタンスを同じインターフェイスで扱うことができる。
上記のように、インターフェイスを使用することで、異なるクラスが共通のインターフェイスを持つことができる。これによって、同じインターフェイスで異なるクラスのインスタンスを扱うことができる。
解いてみよう!継承関連クイズ
継承とは何ですか?
- 継承とは、親クラスの機能を子クラスに引き継ぐことを言います。
- 継承とは、子クラスが親クラスに含まれることを言います。
- 継承とは、多重継承をすることを言います。
解答
答え: 1:継承とは、親クラスの機能を子クラスに引き継ぐことを言います。
継承:親クラスの機能を子クラスに引き継ぐこと。子クラスは親クラスの機能を拡張または変更することができます。
オーバーライドとは何ですか?
- オーバーライドとは、親クラスのメソッドを子クラスで上書きすることを言います。
- オーバーライドとは、子クラスのメソッドが親クラスのメソッドを隠すことを言います。
- オーバーライドとは、子クラスのメソッドを親クラスのメソッドと同名にすることを言います。
解答
答え: 1:オーバーライドとは、親クラスのメソッドを子クラスで上書きすることを言います。
オーバーライド:親クラスのメソッドを子クラスで上書きすること。子クラスでは親クラスのメソッドを定義し直すことで、より特化されたメソッドを提供することができます。
ポリモーフィズムとは何ですか?
- ポリモーフィズムとは、異なる型から同じメソッドを呼び出すことを言います。
- ポリモーフィズムとは、同じ型から異なるメソッドを呼び出すことを言います。
- ポリモーフィズムとは、異なる型から異なるメソッドを呼び出すことを言います。
解答
答え: 1:ポリモーフィズムとは、異なる型から同じメソッドを呼び出すことを言います。
ポリモーフィズム:異なる型から同じメソッドを呼び出すこと。ポリモーフィズムを利用することで、同じメソッド呼び出しを使って、異なる型を扱うことができます。
抽象クラスとは何ですか?
- 抽象クラスとは、親クラスから継承される抽象的なメソッドを含むクラスを言います。
- 抽象クラスとは、実際にはインスタンスを生成することができないクラスを言います。
- 抽象クラスとは、親クラスから継承される具体的なメソッドを含むクラスを言います。
解答
答え: 2:抽象クラスとは、実際にはインスタンスを生成することができないクラスを言います。
抽象クラス:実際にはインスタンスを生成することができないクラス。抽象クラスは継承を前提としていますが、そのままでは使用することができないため、必ず子クラスにて実装される必要のあるメソッドやプロパティを定義することができます。
インターフェイスとは何ですか?
- インターフェイスとは、クラス間で共通の機能を定義するものを言います。
- インターフェイスとは、実際にはインスタンスを生成することができないクラスを言います。
- インターフェイスとは、実装することが必須のメソッドとプロパティを定義するものを言います。
解答
答え: 3:インターフェイスとは、実装することが必須のメソッドとプロパティを定義するものを言います。
インターフェイス:実装することが必須のメソッドとプロパティを定義するもの。複数のクラスに共通の機能を定義するために利用されます。各クラスではインターフェイスで定義されたメソッドやプロパティを実装することが必須となります。
この章のまとめ
オブジェクト指向 応用編についてまとめます。
- 継承を使用することで、既存のクラスの機能を継承し、新しいクラスを作成できます。
- 派生クラスは、基底クラスの機能を継承し、必要に応じて機能を上書きすることができます。
- ポリモーフィズムを使用することで、異なるクラスのインスタンスを同じインターフェイスで扱うことができます。
- 抽象クラスは、インスタンスを生成することができず、派生クラスに共通の機能を提供するために使用されます。
- インターフェイスは、クラスが実装するべきメソッドやプロパティを定義するためのもので、複数のクラスが共通のインターフェイスを持つことができます。



継承やポリモーフィズムなどの基本的な概念から、抽象クラスやインターフェイスなどの応用的な概念まで理解することができました!



継承、派生クラスのオーバーライド、ポリモーフィズム、抽象クラス、インターフェイスなど、これらの概念を理解し、実践的なプログラミングに応用することで、より質の高いプログラムを作成することができるようになります。
次のチャプター
次章の「ワンランク上を目指して 応用編」では、「ジェネリック」「匿名型」「デリゲート」「ラムダ式」「LINQ」といった機能について学びます。



