abstractとは?抽象クラス・抽象メソッドについて学ぶ!Java初心者の勉強

2020-08-16

Javaの勉強をしていてabstractを見かけると難しいと感じてしまっていましたが、abstractについてきちんと理解しようと思います。

abstractとは

「abstract」は「抽象的な」という意味の英語です。まだ中身の決まっていない、具体的でないものを指します。Javaではabstractがつくものは抽象クラス、抽象メソッドの2つがあります。関連でインターフェースもありますが別でまとめています。abstract、抽象と言われるとわかりづらいですが、「abstract = 未完成な部分がある」と考えれば少し理解しやすくなると思います。
抽象の対比として具象がつかわれます。

抽象クラスとは

抽象クラスはabstractがついたクラスです。抽象メソッド(中身のない)と具象メソッド(中身がある)の両方を記述できるクラスです。抽象メソッドが1つでもあるクラスは必ずabstractをつけなければいけません。

構文

アクセス修飾子 abstract class クラス名{
// code
}

抽象クラスにはabstractをつけて抽象クラスであると明記します。

抽象クラスはインスタンス化できない

抽象クラスはnewすることはできません。

サンプルコード

abstract class Circle{
    abstract void print();
}

public class Main {
    public static void main(String[] args) throws Exception {
        Circle test = new Circle(); // コンパイルエラー
    }
}

抽象メソッドとは

抽象メソッドは中身のまだない(未定義)のメソッドです。

構文

アクセス修飾子 abstract 戻り値 メソッド名(引数);

中身を書かないため「{}」波括弧は書かずセミコロン「;」を書きます。

abstractクラスを継承して使う

abstractクラスには未定義のメソッドがあるためインスタンス化できないため、オーバーライドしてメソッドを完成させます。

サンプルコード

abstract class Circle{
    abstract void print(); //抽象メソッド
}

public class CircleChild extends Circle{ // abstractクラスCircleを継承
    @Override
    void print() { // printメソッドをオーバーライド
        System.out.println("abstractを具象化しました!");
    }
}

public class Main {
    public static void main(String[] args) throws Exception {
        CircleChild test = new CircleChild(); //インスタンス化
        test.print(); //メソッドprintを呼び出し
    }
}

結果

abstractを具象化しました!

より複雑なabstractクラスの継承

abstractクラス内の具象メソッドでabstractメソッドを呼び出しています。

abstract class Circle{
    void printA() {
        System.out.println("printA 1回目");
        printB();
        System.out.println("printA 2回目");
    }
    abstract void printB();
}

public class CircleChild extends Circle{ // abstractクラスCircleを継承
    @Override
   void printB(){ // printBメソッドをオーバーライド
      System.out.println("printB");
   }
}

上記サンプルコードをMainクラスで実行します。
Circle型にCircleChildインスタンスを生成し、printメソッドを呼び出すとどのようになるでしょうか。

public class Main {
    public static void main(String[] args) throws Exception {
        Circle test = new CircleChild(); //インスタンス化
        test.print(); //メソッドprintを呼び出し
    }
}

結果

printA 1回目
printB
printA 2回目

親クラスで作成したabstractメソッドは子クラスでオーバーライドしたメソッド内容が反映されていることがわかります。

おわり

abstractと子クラスが1つずつならなんとか読み取れるけれど、アクセス修飾子やポリモーフィズムなどがからんで複雑になってくるともうわけがわからないですね。

Java

Posted by Nakamoto