1. 共通基本クラス

今日は興味深い話題を盛り沢山に楽しみましょう。チェスの駒を表すすべてのクラスを単純化するために基本クラスを導入したときのことを覚えていますか? そう願っています 🙂ChessItem

ここで、各ピースがdraw()画面上での描画を処理するメソッドを持っていると想像してください。このメソッドを呼び出すdraw()と、ピースが現在の座標で描画されます。このメソッドを基本クラスに移動すると便利です。

メソッドが ChessItem 基本クラスにある場合はdraw()、ピース クラスでメソッドをオーバーライドして、次のようなエレガントなコードを書くことができます。

class ChessBoard
{
   public void drawAllChessItems()
   {
      // Add the pieces to the list
      ArrayList<ChessItem> items = new ArrayList<ChessItem>();
      items.add(new King());
      items.add(new Queen());
      items.add(new Bishop());

      // Draw them regardless of their type
      for(ChessItem item: items)
      {
         item.draw();
      }
   }
}

基本クラスを導入することでChessItem、コードを大幅に簡素化することができました。各クラスのメソッドを個別に呼び出す必要がなくなり、すべてのオブジェクトを 1 つのコレクションに簡単に格納できるようになりました。

しかし、ここで興味深い質問があります。クラスdraw()内で直接宣言されたメソッドはChessItem画面上に何を描画すべきでしょうか? 結局のところ、チェスにはそのような駒はないので、引くものは何もありません。

まさにその通りです。さらに、ChessItemオブジェクトを直接作成することは意味がありません。これはチェスの駒ではなく、単なる抽象化、つまり私たちが便宜のために作成したクラスです。これがOOPでの抽象化の仕組みです。重要なデータとメソッド (すべての部分で共有されるもの) を基本クラスに移動し、それらの違いを個別の子孫クラスに保持します。


2. 抽象クラス

抽象クラス

このような状況に備えて、Java には抽象クラスという特別な種類のクラスがあります。これらは、プログラマが同様のクラスを操作しやすくし、クラス内の重複コードの量を減らすように設計されています。

抽象クラスについて知っておくべきことが 3 つあります。

実装のないメソッド

抽象クラスは、実装なしでメソッド宣言を持つことができます。これがまさにメソッドを抽象化する理由です。メソッド本体はセミコロンに置き換えるだけです。そしてメソッド名の前にキーワードを書きますabstract。例:

public abstract class ChessItem
{
   public int x, y; // Coordinates
   private int value; // The piece's value
   public int getValue() // Ordinary method that returns value field
   {
      return value;
   }

   public abstract void draw(); // Abstract method. The implementation is missing.
}

抽象クラス

実装のない各メソッドには、abstract キーワードが付けられます。クラスに抽象メソッドが 1 つでもある場合、そのクラスもキーワードでマークされますabstract

オブジェクトの作成を禁止する

抽象クラスのオブジェクトを作成することはできません。このようなコードはコンパイルできません。

コード 説明
ChessItem item = new ChessItem();
item.draw();
このコードはコンパイルできません:
ChessItem item = new Queen();
item.draw();
でもこれならできるよ

抽象クラスの継承

クラスが抽象クラスを継承する場合、継承されたすべての抽象メソッドをオーバーライドする必要があります。つまり、それらの実装を作成する必要があります。それ以外の場合は、クラス自体も抽象として宣言する必要があります。

クラス内で直接宣言された、または親クラスから継承された未実装のメソッドが 1 つでもクラスにある場合、そのクラスは抽象クラスとみなされます。

そして、なぜこれだけが必要なのでしょうか? なぜ抽象クラスが必要なのでしょうか? 普通のものを代用することはできないでしょうか?また、抽象メソッドの代わりに、メソッド本体として 2 つの空の中括弧を記述することはできないでしょうか。

我々は出来た。ただし、これらの制限はprivate修飾子に似ています。private キーワードを使用して、他のプログラマがデータに直接アクセスすることを意図的に防ぎ、クラスを作成するときにパブリック メソッドのみを使用するように強制します。

抽象クラスも同様です。抽象クラスの作成者は、クラスのオブジェクトが作成されることを望んでいません。代わりに、作成者は、抽象メソッドが抽象クラスから継承され、オーバーライドされることを期待しています。

このアプローチの利点は、大規模なプロジェクトではすぐに明らかです。クラスが増えるほど、その役割をより明確に描写する必要があります。近い将来、このアプローチの利点が分かるでしょう。すべてのことはこれを通過します。