【C#入門】MyButtonで継承を体験しよう|Buttonを引き継いで機能を追加する

広告

前回は、ButtonControl を継承しているため、TextSizeBackColor などの共通機能を使えることを確認しました。

今回は、自分で Button を継承した MyButton クラスを作ります。

既存のボタンの機能を受け継ぎながら、自分のアプリ専用の情報を追加することが目標です。

前の記事:なぜButtonのプロパティは多いのか(継承とis-a)


① まずは空のMyButtonを作る

Windowsフォームアプリのプロジェクトに、MyButton.cs というクラスを追加します。

using System.Windows.Forms;

public class MyButton : Button
{
}

注目するのは、クラス名の後ろにある : Button です。

public class MyButton : Button

これは、MyButtonButton を継承するという意味です。

  • Button:基底クラス(継承元)
  • MyButton:派生クラス(継承して作るクラス)

中身が空でも、MyButton はすでにボタンとしての機能を持っています。


② 本当にButtonの機能を使えるか確認する

Form1 のコンストラクターで MyButton のオブジェクトを作ってみましょう。

using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        MyButton myButton = new MyButton();
        myButton.Text = "自作ボタン";
        myButton.AutoSize = true;
        myButton.BackColor = Color.Honeydew;
        myButton.Location = new Point(30, 30);

        Controls.Add(myButton);
    }
}

MyButton クラスには、TextBackColor を自分で定義していません。それでも使えるのは、Button から受け継いでいるからです。

Controls.Add(myButton) でフォームへ追加できるのも、MyButtonControl の一種だからです。


③ MyButtonだけの情報を追加する

次に、普通の Button にはない Category プロパティを追加します。

using System.Drawing;
using System.Windows.Forms;

public class MyButton : Button
{
    public string Category { get; set; } = "未分類";

    public MyButton()
    {
        Text = "自作ボタン";
        AutoSize = true;
        BackColor = Color.Honeydew;
    }
}

これで MyButton は、次の2種類の機能を持つクラスになりました。

  • Button から受け継いだ機能:TextBackColorClick など
  • MyButton で追加した機能:Category
ButtonのText・BackColor・ClickをMyButtonが受け継ぎ、独自のCategoryプロパティを追加する継承の仕組みを示す図
継承では、元の機能を利用しながら、自分のクラスに必要な機能を追加できます。

④ Categoryを設定してクリック時に表示する

Form1 側で Category を設定し、クリックしたときに内容を表示します。

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        MyButton myButton = new MyButton
        {
            Category = "学習",
            Location = new Point(30, 30)
        };

        myButton.Click += MyButton_Click;
        Controls.Add(myButton);
    }

    private void MyButton_Click(object sender, EventArgs e)
    {
        if (sender is MyButton button)
        {
            MessageBox.Show($"分類: {button.Category}");
        }
    }
}

ボタンをクリックすると、次のメッセージが表示されます。

分類: 学習

Click は継承した機能、Category は追加した機能です。両方を同じ MyButton オブジェクトから利用できます。


⑤ is-aで関係を確認する

継承関係は、「〜は〜の一種である」と読めます。

  • MyButtonButton の一種である
  • ButtonControl の一種である
  • したがって、MyButtonControl の一種である
Control
  └─ Button
       └─ MyButton

この「一種である」という関係を is-a と呼びます。


⑥ 継承はコピーではない

MyButton を作るとき、Button のソースコードをコピーしているわけではありません。

Button との継承関係を宣言することで、公開されている機能や派生クラスから利用できる機能を受け継いでいます。

また、基底クラスのすべてを自由に触れるわけではありません。private なメンバーは派生クラスから直接アクセスできません。


⑦ デザイナーではなくコードから試す理由

自作コントロールは、プロジェクトをビルドするとツールボックスに表示されることがあります。ただし、Visual Studio のバージョンやプロジェクトの状態によって表示方法が異なることがあります。

この記事では継承そのものに集中するため、まずは new MyButton()Controls.Add() を使ってコードから配置しています。


⑧ 完成コード

MyButton.cs

using System.Drawing;
using System.Windows.Forms;

public class MyButton : Button
{
    public string Category { get; set; } = "未分類";

    public MyButton()
    {
        Text = "自作ボタン";
        AutoSize = true;
        BackColor = Color.Honeydew;
    }
}

Form1.cs

using System;
using System.Drawing;
using System.Windows.Forms;

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        MyButton myButton = new MyButton
        {
            Category = "学習",
            Location = new Point(30, 30)
        };

        myButton.Click += MyButton_Click;
        Controls.Add(myButton);
    }

    private void MyButton_Click(object sender, EventArgs e)
    {
        if (sender is MyButton button)
        {
            MessageBox.Show($"分類: {button.Category}");
        }
    }
}

⑨ まとめ

  • class MyButton : ButtonButton を継承できる
  • 中身が空でも、MyButton はボタンとして動く
  • 継承した機能を使いながら、独自のプロパティや処理を追加できる
  • MyButton is a Button のような関係を is-a と呼ぶ
  • 継承はソースコードのコピーではない

次回は、ButtonLabelTextBox を共通の Control 型としてまとめて扱います。

次の記事:Controlとしてまとめて扱う

シリーズ目次:WinFormsで学ぶ「継承」入門

訪問数 6 回, 今日の訪問数 6回

広告