「スーパー」と「サブ」ってどういう由来?
質問:じゃあ、「サブクラス」の「サブ」ってどういう意味? 「スーパークラス」の「スーパー」ってどういう意味? 特に「スーパー」の方は意味が合わないんだけど。
解答:「スーパーセット」と「サブセット」という用語が元になっています。「超」とか「予備」という意味は忘れた方がいいでしょう。
前ページで出てきた「スーパークラス」と「サブクラス」、そしてインスタンスの関係については分かったと思います。
でもそうすると、「スーパークラス」とか「サブクラス」ってどういう理由でこんな言葉が使われているんでしょう。「スーパー」と「サブ」にどんな意味が?
実はこれは、数学用語が元になっています。
数学用語に「スーパーセット」「サブセット」という用語があって、それが元になって「スーパークラス」「サブクラス」という名前が付けられました(参考:部分集合 - Wikipedia。部分集合=サブセット)。
その理由は、ちょっと複雑です。
まず、今回はクラスからではなくインスタンスから考えてみましょう。
実際、プログラムを作るときにもクラスというよりはインスタンスをイメージして作ると思います。どんな機能を持つインスタンスが必要か――そこからクラスという設計図を考えていくわけです。
今回の例では、2つのインスタンスが必要、ということでこんなインスタンスをイメージした、ということにします。
インスタンス1はmethodA()メソッドとmethodB()メソッドを持っています。
インスタンス2はmethodA()メソッドとmethodC()メソッドを持っています。
こんなインスタンスがあれば目的のプログラムが動く、と考えたわけです。
さて次に、これらのインスタンスから機能(フィールドやメソッド)を抜き出して、共通の機能を図にします。
インスタンス1とインスタンス2は、共通の機能としてmethodA()を持っています。なので、このmethodA()メソッドを大きな円(ピンク)の中に書きます。
その大きな円の中に小さな円を2つ書き、インスタンス1とインスタンス2それぞれの機能を書きます。
インスタンス1だけの機能はmethodB()メソッドなので、これを小さい円の1つ(橙)に書きます。
インスタンス2だけの機能はmethodC()メソッドなので、これを小さい円の1つ(緑)に書きます。
このように図を書くと、「インスタンス1の機能」は「橙」の機能+「ピンク」の機能、「インスタンス2」の機能は「緑」の機能+「ピンク」の機能ということになります。
この図の内、全体を覆うピンクの範囲を「スーパーセット」、その中にある橙と緑の小さい範囲を「サブセット」と言います。
これは数学用語で、単純に「覆ってる側=スーパーセット」「覆われてる側=サブセット」と考えればいいでしょう。
この図ができたら、最後にこの図を元にクラスを作ります。
「共通機能」の部分を一クラスにして、このクラスから継承して、インスタンス1の機能だけを持つクラスと、インスタンス2の機能だけを持つクラスを作ります。
インスタンス1とインスタンス2の共通機能を持つクラスとしてGeneralSuperクラスを作ります。
インスタンス1の機能だけを持つクラスとしてSpecialSub1クラスを作ります。
インスタンス2の機能だけを持つクラスとしてSpecialSub2クラスを作ります。
SpecialSub1クラスとSpecialSub2クラスはGeneralSuperクラスから継承するので、インスタンスを作ると共通機能も持つことができます。
こうして作られたクラスの内、共通部分のクラスは「スーパーセット」の機能を持つクラスなので「スーパークラス」と呼びます。
そして、各インスタンスの部分のクラスは「サブセット」の機能を持つクラスなので「サブクラス」と呼びます。
というわけで、「スーパークラス」「サブクラス」という名前が付けられたわけです。
ちなみにできたクラスはこんな感じ。
/**
* 共通部分のクラス。
*/
class GeneralSuper
{
/**
* methodA()メソッド。
* 2つのインスタンス両方が持つメソッドです。
*/
void methodA()
{
// 何か処理をするはず。
}
}
/**
* GeneralSuperクラスから継承した、サブクラス。
* インスタンス1の機能を持ちます。
*/
class SpecialSub1 extends GeneralSuper
{
/**
* methodB()メソッド。
* インスタンス1が持つメソッドです。
*/
void methodB()
{
// 何か処理をするはず。
}
}
/**
* GeneralSuperクラスから継承した、サブクラス。
* インスタンス2の機能を持ちます。
*/
class SpecialSub2 extends GeneralSuper
{
/**
* methodC()メソッド。
* インスタンス2が持つメソッドです。
*/
void methodC()
{
// 何か処理をするはず。
}
}
// SpecialRunner.java /** * 共通部分のクラス。 */ class GeneralSuper { /** * methodA()メソッド。 * 2つのインスタンス両方が持つメソッドです。 */ void methodA() { // 何か処理をするはず。 } } /** * GeneralSuperクラスから継承した、サブクラス。 * インスタンス1の機能を持ちます。 */ class SpecialSub1 extends GeneralSuper { /** * methodB()メソッド。 * インスタンス1が持つメソッドです。 */ void methodB() { // 何か処理をするはず。 } } /** * GeneralSuperクラスから継承した、サブクラス。 * インスタンス2の機能を持ちます。 */ class SpecialSub2 extends GeneralSuper { /** * methodC()メソッド。 * インスタンス2が持つメソッドです。 */ void methodC() { // 何か処理をするはず。 } }
と、この解説は2つの面を持っています。
1つは「スーパークラスとかサブクラスって用語は、意味を考えなくてもいいよ」ということ。単語の意味は考えず、継承元はスーパークラス、継承先はサブクラスって憶えましょう。
もう1つは「インスタンスからクラスを考える」ということ。実はこっちはとってもオブジェクト指向的な考え方で、この考え方が分かるとオブジェクト指向の理解に一歩近づけます。ちなみに今回のように「共通部分を抜き出してひとまとめにする」という考え方を「汎化」(はんか)と言います。
まぁ実際の所、この辺はオブジェクト指向でももう少し先の話になりますので、このテキスト範囲を超えた内容になります。将来的にはこんなことを勉強するんだよ、とでも憶えておいてください。