1.ペガサス

OOPの3 番目の原則である継承を詳しく見てみましょう。これは、頻繁に使用する非常に興味深いトピックです。初心者にとって、プログラミングは魔法と区別がつきません。それでは、興味深い例えから始めましょう...;

あなたが空飛ぶ馬を作りたい魔法使いだとしましょう。一方で、ペガサスを召喚してみることもできます。しかし、ペガシは自然界には存在しないため、これは非常に困難です。自分自身で多くのことを行う必要があります。馬を捕まえてその翼を呼び起こす方がはるかに簡単です。

プログラミングでは、このプロセスを「継承」と呼びます。非常に複雑なクラスを作成する必要があるとします。コードを最初から作成し、すべてを長時間テストしてエラーを探すには長い時間がかかります。なぜ難しい道を行くのでしょうか?そのようなクラスがすでに存在するかどうかを確認することをお勧めします。

必要な機能の 80% を実装するメソッドを持つクラスを見つけたとします。次にそれをどうしますか? そのコードをクラスにコピーするだけです。ただし、この解決策にはいくつかの欠点があります。

  1. 見つかったクラスはすでにバイトコードにコンパイルされており、そのソース コードにアクセスできない可能性があります。
  2. このクラスのソース コードは入手可能ですが、あなたが働いている会社では、他人のコードを 6 行でも使用しただけで数十億で訴えられる可能性があります。そして雇用主はあなたを告訴するでしょう。
  3. 大量のコードの不必要な重複。さらに、外部クラスの作成者がその中にバグを見つけて修正した場合でも、バグは残ったままになります。

もっと洗練された解決策があり、元のクラスのコードに合法的にアクセスする必要はありません。Java では、そのクラスをクラスの親として宣言するだけで済みます。これは、そのクラスのコードを独自のコードに追加することと同じになります。あなたのクラスは、親クラスのすべてのデータとすべてのメソッドを参照します。たとえば、次のようにすることができます。「馬」を継承し、「翼」を追加して「ペガサス」を取得します。


2. 共通基本クラス

継承は他の目的にも使用できます。非常によく似たクラスが 10 個あるとします。彼らは同じデータとメソッドを持っています。特別な基本クラスを作成し、データ (および関連するメソッド) をこの基本クラスに移動し、それらの 10 個のクラスを子孫として宣言できます。言い換えれば、各クラスでは、その親クラスがこの基本クラスであることを示します。

抽象化の利点がカプセル化と並行してのみ明らかにされるのと同様に、継承の利点もポリモーフィズムを使用すると大幅に強化されます。しかし、それについてはもう少し後で学びます。今日は、継承の使用例をいくつか見ていきます。

チェスの駒

人間のユーザーとチェスをするプログラムを作成しているとします。したがって、駒を表現するクラスが必要になります。どのようなクラスになるでしょうか?

チェスをプレイしたことがあるなら、明白な答えは、キング、クイーン、ビショップ、ナイト、ルーク、ポーンです。

ただし、クラス自体は依然として各部分に関する情報を保存する必要があります。たとえば、x 座標と y 座標、およびピースの値です。結局のところ、一部の作品は他の作品より価値があります。

さらに、ピースの動きも異なります。これは、クラスが異なる動作を実装することを意味します。これらをクラスとして定義する方法は次のとおりです。

class King
{
   int x;
   int y;
   int worth;

   void kingMove()
   {
     // Code that decides
     // how to move
     // the king
   }
}
class Queen
{
   int x;
   int y;
   int worth;

   void queenMove()
   {
     // Code that decides
     // how to move
     // the queen
   }
}
class Rook
{
   int x;
   int y;
   int worth;

   void rookMove()
   {
     // Code that decides
     // how to move
     // the rook
   }
}
class Knight
{
   int x;
   int y;
   int worth;

   void knightMove()
   {
     // Code that decides
     // how to move
     // the knight
   }
}
class Bishop
{
   int x;
   int y;
   int worth;

   void bishopMove()
   {
     // Code that decides
     // how to move
     // the bishop
   }
}
class Pawn
{
   int x;
   int y;
   int worth;

   void pawnMove()
   {
     // Code that decides
     // how to move
     // the pawn
   }
}

これはチェスの駒についての非常に原始的な説明です。

共通の基本クラス

ここでは、継承を使用してコードの量を減らす方法を示します。共通のメソッドとデータを共通のクラスに組み込むことができます。と呼びますChessItemこのクラスはどのチェスの駒にも対応していないため、のオブジェクトをChessItem class作成しても意味がありません。そうは言っても、このクラスは非常に役立つことがわかります。

class King extends ChessItem
{
   void kingMove()
   {
     // Code that decides
     // how to move the king
   }
}
class Queen extends ChessItem
{
   void queenMove()
   {
     // Code that decides
     // how to move the queen
   }
}
class Rook extends ChessItem
{
   void rookMove()
   {
     // Code that decides
     // how to move the rook
   }
}
class ChessItem
{
   int x;
   int y;
   int worth;
}
class Knight extends ChessItem
{
   void knightMove()
   {
     // Code that decides
     // how to move the knight
   }
}
class Bishop extends ChessItem
{
   void bishopMove()
   {
     // Code that decides
     // how to move the bishop
   }
}
class Pawn extends ChessItem
{
   void pawnMove()
   {
     // Code that decides
     // how to move the pawn
   }
}

これは、同様のオブジェクトのコードを簡素化する優れた方法です。 この利点は、プロジェクト内に数千の異なるオブジェクトと数百のクラスがある場合に特に顕著です。したがって、親 (基本) クラスを適切に選択すると、ロジックが大幅に簡素化されるだけでなく、コードが 10 分の 1 に削減されます。


3. クラスの継承 —extends

では、クラスを継承するには何が必要でしょうか? extendsあるクラスが別のクラスを継承するには、子クラスの宣言の後にキーワードを記述してから、親クラスの名前を記述する必要があります。通常は次のようになります。

class Descendant extends Parent

これは、Descendant クラスを宣言するときに記述する必要があるものです。ちなみに、クラスは一つのクラスしか継承できません。

この写真では、牛が豚を継承し、豚が鶏を継承し、豚が卵を継承したことがわかります。親は一人だけ!このような継承は必ずしも論理的であるとは限りません。しかし、豚しかなくて本当に牛が必要な場合、プログラマーは豚から牛を作りたいという衝動に抵抗できないことがよくあります。

Java には多重継承がありません。クラスは 2 つのクラスを継承できません。各クラスは親クラスを 1 つだけ持つことができます。親クラスが指定されていない場合、親クラスは ですObject

とはいえ、Java にはインターフェイスの多重継承があります。これにより、問題がわずかに軽減されます。インターフェイスについては少し後で説明しますが、今は継承について調べていきましょう。