抽象クラス
| 日本語 | かりそめのクラス |
| 英語 | abstract class |
| ふりがな | ちゅうしょうくらす |
| フリガナ | チュウショウクラス |
インターフェイスとクラスの中間。
インターフェイスのように「実装のないメソッド」を持つクラス。「abstractクラス」と呼ばれることもある。
クラスの宣言で、abstractという予約語をclassの前に付けることで、そのクラスは「抽象クラス」と見なされる。
実装のないメソッドを作る場合には、メソッドの宣言の、戻り値の前にabstractを付け、実装を行わず;で閉じればよい。この書式はインターフェイスのメソッドと同じである。この「実装のないメソッド」を「抽象メソッド」と呼ぶ。
インターフェイスと同じく「中身がない」ため、インスタンスを作成できない。使用するためには、継承してサブクラスを宣言し、その中で抽象メソッドの実装を定義する必要がある。抽象メソッドの実装方法は、インターフェイスと同じく、オーバーライドすればよい。
サブクラスを作らなければ使用できないため、ポリモーフィズムを行うための機能と言える。
だが、「すべての抽象メソッドにabstractを付ける必要がある」「れっきとしたクラスのため、インターフェイスのように既存のクラスに実装することができない(多重継承になってしまう)」等、使い勝手の悪い面が多いためあまり使われない。
クラスによるポリモーフィズムを使用する場合に、スーパークラスに「一般的な実装」がなく、さらに「必ずサブクラスで実装して欲しい」メソッドがある場合に使用するのがいいだろう。
インターフェイスのように「実装のないメソッド」を持つクラス。「abstractクラス」と呼ばれることもある。
クラスの宣言で、abstractという予約語をclassの前に付けることで、そのクラスは「抽象クラス」と見なされる。
実装のないメソッドを作る場合には、メソッドの宣言の、戻り値の前にabstractを付け、実装を行わず;で閉じればよい。この書式はインターフェイスのメソッドと同じである。この「実装のないメソッド」を「抽象メソッド」と呼ぶ。
インターフェイスと同じく「中身がない」ため、インスタンスを作成できない。使用するためには、継承してサブクラスを宣言し、その中で抽象メソッドの実装を定義する必要がある。抽象メソッドの実装方法は、インターフェイスと同じく、オーバーライドすればよい。
サブクラスを作らなければ使用できないため、ポリモーフィズムを行うための機能と言える。
だが、「すべての抽象メソッドにabstractを付ける必要がある」「れっきとしたクラスのため、インターフェイスのように既存のクラスに実装することができない(多重継承になってしまう)」等、使い勝手の悪い面が多いためあまり使われない。
クラスによるポリモーフィズムを使用する場合に、スーパークラスに「一般的な実装」がなく、さらに「必ずサブクラスで実装して欲しい」メソッドがある場合に使用するのがいいだろう。
参考サイト
- (参考サイトはありません)
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// SubAbstractClassクラスを使用してみます。
SubAbstractClass subAbstractClass = new SubAbstractClass();
subAbstractClass.output();
// SubAbstractClass#output()
// 抽象メソッド以外も普通に呼び出せます。
subAbstractClass.output3();
// AbstractClass#output3()
// サブクラスからスーパークラス(抽象クラス)への
// アップキャストは可能です。その際、ポリモーフィズムが
// 適用されるのでスーパークラスからサブクラスのメソッドを
// 呼び出すことができます。
AbstractClass abstractClass = subAbstractClass;
abstractClass.output();
// SubAbstractClass#output()
// 抽象クラスの抽象メソッドには実装がないため、
// 抽象クラスのインスタンスは作成できません。
// abstractClass = new AbstractClass();
// コンパイルエラー:
// AbstractClass のインスタンスを生成することができません。
// ちなみに、たとえAbstractClassクラスに抽象メソッドが
// 存在しなかったとしても、このコンパイルエラーは
// 発生します。クラスに付けられた「abstract」が、
// そのクラスが抽象クラスであることの証となっているからです。
}
}
/**
* AbstractClassクラスを宣言します。
*/
abstract class AbstractClass
{
/**
* 抽象メソッドを用意します。
*/
public abstract void output();
// 実装はありません。
// もし抽象メソッドに実装があると、
// 以下のようなコンパイルエラーが
// 発生します。
// public void output2(){}
// コンパイルエラー:
// 抽象メソッドは本体を指定しません。
/**
* 普通のメソッドも置けます。
* そこがインターフェイスとの違いです。
*/
public void output3()
{
System.out.println( "AbstractClass#output3()" );
}
}
/**
* AbstractClassクラスのサブクラスSubAbstractClassを宣言します。
*/
class SubAbstractClass extends AbstractClass
{
/**
* AbstractClassクラスのメソッドを実装します。
* 方法はオーバーライドと同じ。
* 同名、同引数、同戻り値のメソッドを作ってください。
*/
public void output()
{
System.out.println( "SubAbstractClass#output()" );
}
// 抽象クラスから継承する場合には、すべての抽象メソッドを
// 実装する必要があります。たとえば、output()メソッドを
// 作り忘れると、以下のコンパイルエラーが発生します。
// コンパイルエラー:
// クラスは継承された抽象メソッド AbstractClass.output() をインプリメントする必要があります。
}
public class Sample
{
public static void main( String[] args )
{
// SubAbstractClassクラスを使用してみます。
SubAbstractClass subAbstractClass = new SubAbstractClass();
subAbstractClass.output();
// SubAbstractClass#output()
// 抽象メソッド以外も普通に呼び出せます。
subAbstractClass.output3();
// AbstractClass#output3()
// サブクラスからスーパークラス(抽象クラス)への
// アップキャストは可能です。その際、ポリモーフィズムが
// 適用されるのでスーパークラスからサブクラスのメソッドを
// 呼び出すことができます。
AbstractClass abstractClass = subAbstractClass;
abstractClass.output();
// SubAbstractClass#output()
// 抽象クラスの抽象メソッドには実装がないため、
// 抽象クラスのインスタンスは作成できません。
// abstractClass = new AbstractClass();
// コンパイルエラー:
// AbstractClass のインスタンスを生成することができません。
// ちなみに、たとえAbstractClassクラスに抽象メソッドが
// 存在しなかったとしても、このコンパイルエラーは
// 発生します。クラスに付けられた「abstract」が、
// そのクラスが抽象クラスであることの証となっているからです。
}
}
/**
* AbstractClassクラスを宣言します。
*/
abstract class AbstractClass
{
/**
* 抽象メソッドを用意します。
*/
public abstract void output();
// 実装はありません。
// もし抽象メソッドに実装があると、
// 以下のようなコンパイルエラーが
// 発生します。
// public void output2(){}
// コンパイルエラー:
// 抽象メソッドは本体を指定しません。
/**
* 普通のメソッドも置けます。
* そこがインターフェイスとの違いです。
*/
public void output3()
{
System.out.println( "AbstractClass#output3()" );
}
}
/**
* AbstractClassクラスのサブクラスSubAbstractClassを宣言します。
*/
class SubAbstractClass extends AbstractClass
{
/**
* AbstractClassクラスのメソッドを実装します。
* 方法はオーバーライドと同じ。
* 同名、同引数、同戻り値のメソッドを作ってください。
*/
public void output()
{
System.out.println( "SubAbstractClass#output()" );
}
// 抽象クラスから継承する場合には、すべての抽象メソッドを
// 実装する必要があります。たとえば、output()メソッドを
// 作り忘れると、以下のコンパイルエラーが発生します。
// コンパイルエラー:
// クラスは継承された抽象メソッド AbstractClass.output() をインプリメントする必要があります。
}
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// SubAbstractClassクラスを使用してみます。
SubAbstractClass subAbstractClass = new SubAbstractClass();
subAbstractClass.output();
// SubAbstractClass#output()
// 抽象メソッド以外も普通に呼び出せます。
subAbstractClass.output3();
// AbstractClass#output3()
// サブクラスからスーパークラス(抽象クラス)への
// アップキャストは可能です。その際、ポリモーフィズムが
// 適用されるのでスーパークラスからサブクラスのメソッドを
// 呼び出すことができます。
AbstractClass abstractClass = subAbstractClass;
abstractClass.output();
// SubAbstractClass#output()
// 抽象クラスの抽象メソッドには実装がないため、
// 抽象クラスのインスタンスは作成できません。
// abstractClass = new AbstractClass();
// コンパイルエラー:
// AbstractClass のインスタンスを生成することができません。
// ちなみに、たとえAbstractClassクラスに抽象メソッドが
// 存在しなかったとしても、このコンパイルエラーは
// 発生します。クラスに付けられた「abstract」が、
// そのクラスが抽象クラスであることの証となっているからです。
}
}
/**
* AbstractClassクラスを宣言します。
*/
abstract class AbstractClass
{
/**
* 抽象メソッドを用意します。
*/
public abstract void output();
// 実装はありません。
// もし抽象メソッドに実装があると、
// 以下のようなコンパイルエラーが
// 発生します。
// public void output2(){}
// コンパイルエラー:
// 抽象メソッドは本体を指定しません。
/**
* 普通のメソッドも置けます。
* そこがインターフェイスとの違いです。
*/
public void output3()
{
System.out.println( "AbstractClass#output3()" );
}
}
/**
* AbstractClassクラスのサブクラスSubAbstractClassを宣言します。
*/
class SubAbstractClass extends AbstractClass
{
/**
* AbstractClassクラスのメソッドを実装します。
* 方法はオーバーライドと同じ。
* 同名、同引数、同戻り値のメソッドを作ってください。
*/
public void output()
{
System.out.println( "SubAbstractClass#output()" );
}
// 抽象クラスから継承する場合には、すべての抽象メソッドを
// 実装する必要があります。たとえば、output()メソッドを
// 作り忘れると、以下のコンパイルエラーが発生します。
// コンパイルエラー:
// クラスは継承された抽象メソッド AbstractClass.output() をインプリメントする必要があります。
}




