Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。

abstract

このページではabstract修飾子について説明します。

概要

abstractはクラス・メソッド宣言時に付与し、クラス・メソッドを抽象クラス(abstractクラス)・抽象メソッド(abstractメソッド)として宣言します。抽象クラスはそのクラス自身のオブジェクトを生成することはできません。通常抽象クラスは実装のないいくつかの抽象メソッドを持っています。抽象クラスをサブクラスで継承し、そのサブクラス内で抽象クラスで実装されていない抽象メソッドを実装(オーバーライド)しオブジェクトを生成する形をとります。

抽象クラス_1

抽象クラスは共通の機能を表現し、個々が持つ独自の機能はそれぞれのサブクラスで実装したい場合に使用します。例えば「自動車」といったクラスがあるとします。座席・ウィンドウといった共通の機能は「自動車」クラスで実装できますが、エンジン・ブレーキといった車種によって異なる機能をすべて「自動車」クラスの中で実装することは困難です。そこで共通の機能のみを「自動車」クラスの中で実装し、「自動車」クラスを抽象クラスとして宣言します。そしてエンジン・ブレーキと言った個々の機能は「自動車」抽象クラスを継承したサブクラス(例えば「ベンツ」クラス、「フェラーリ」クラス)の中で実装します。

抽象クラス_2

使用方法

抽象メソッドは以下の枠内のフォーマットで宣言されます。抽象メソッドは実装を持たないため、{}は必要ありません。

abstract 戻り型 メソッド名(引数型 引数名);

抽象クラスは以下の枠内のフォーマットで宣言されます。

abstract class クラス名 { クラス本体 }

抽象クラスには以下のルールがあります。

  1. 抽象クラスのオブジェクトを生成することはできません。
  2. 抽象クラスには抽象メソッドがあってもいいし、抽象メソッドでないメソッドがあってもいいです。しかし、抽象メソッドがあるクラスは必ず抽象クラスとして宣言しなければいけません。
  3. 抽象メソッドがない、抽象クラスを宣言することもできます。かならず継承が行われ、なんらかのメソッドの変更があることを表します。
  4. 抽象クラスを継承したサブクラスで抽象メソッドを実装(オーバーライド)しない場合、そのサブクラスは抽象クラスとして宣言されます。

【例1】計算結果を表示するメソッドを抽象クラスで実装し、2つの異なる消費税率での計算方法を抽象クラスを継承したサブクラスで実装する例です。

//(1)抽象クラスの宣言
abstract class SuperClass {
    int price = 100;
    //共通機能は抽象クラス内で実装
    void show(int taxprice) {
        System.out.println(taxprice + "円です。");
    }
    //個々で異なる機能はヘッダーのみ宣言
    abstract void calculate();
}
//(2)抽象クラスを継承
class SubA extends SuperClass {
    //抽象クラスで宣言されたcalculateメソッドの
    //実装(オーバーライド)
    void calculate(){
        show((int)(price * 1.05));
    }
}
//(3)抽象クラスを継承
class SubB extends SuperClass {
    //抽象クラスで宣言されたcalculateメソッドの
    //実装(オーバーライド)
    void calculate(){
        show((int)(price * 1.03));
    }
}
class ExClass18 {
    public static void main(String[] args) {
        SubA objectA = new SubA();
        SubB objectB = new SubB();
        objectA.calculate();  //(4)
        objectB.calculate();  //(5)
    }
}

解説1

  1. (1)抽象クラスSuperClassを宣言し、共通機能である課税後の価格を表示するshowメソッドの実行を行います。課税計算を行うcalculateメソッドは課税率により異なるため、ヘッダーのみ宣言します。
  2. (2)抽象クラスSuperClassを継承したSubAクラスを宣言し、SuperClassクラスで実装されなかったcalculateメソッドの実装を行います。ここでは課税率を5%として計算します。
  3. (3)抽象クラスSuperClassを継承したSubBクラスを宣言し、SuperClassクラスで実装されなかったcalculateメソッドの実装を行います。ここでは課税率を3%として計算します。
  4. (4)SubAクラスオブジェクトobjectAを通してcalculateメソッドを呼び出し、消費税率5%での計算を行います。
  5. (5)SubBクラスオブジェクトobjectBを通してcalculateメソッドを呼び出し、消費税率3%での計算を行います。

実行結果1

D:\JAVA>javac ExClass18.java

D:\JAVA>java ExClass18
105円です。
103円です。

D:\JAVA>

抽象クラスとインタフェースの違い

メソッドのヘッダーのみ宣言し、実装を継承したサブクラスに任せる(インタフェースの場合はインプリメントしたクラスに任せる)といったことを考えると抽象クラスとインタフェースは似た役割をはたします。

しかし両者には大きな違いがあります。その違いを以下に記載します。

  1. 抽象クラスには抽象メソッドと抽象メソッドでないメソッドの両方を宣言することができますが、インタフェースは抽象メソッドのみしか宣言することができません。
  2. サブクラスで継承できる抽象クラスはJavaは多重継承をサポートしていないため、1つのみです。インプリメントするインタフェースは複数インプリメントすることができます。
  3. 抽象クラスの機能を利用するためには抽象クラスを継承する必要があります。そのため、その機能は継承関係内に限られます。インタフェースはインプリメントにより利用することができます。そのため、その機能が継承関係内に限られることはありません。

14abstract