抽象クラスはインスタンスを作れません
抽象クラスが普通のクラスと大きく異なる点に「インスタンスを作ることができない」という点があります。
実際にコンパイルエラーを出して確認してみましょう。
/**
* 抽象クラス。
*/
abstract class AbstractClass
{
/**
* 抽象メソッド。
*/
abstract void printMyName();
}
/**
* 実行用クラス。このクラスを実行してください。
*/
class AbstractClassRunner
{
public static void main( String[] args )
{
// 抽象クラスはインスタンスを作れません!
// AbstractClass ref = new AbstractClass();
// コンパイルエラー:
// AbstractClassRunner.java:18:
// AbstractClass は abstract です。
// インスタンスを生成することはできません。
// AbstractClass ref = new AbstractClass();
// ^
// でも参照型変数は作れます。
AbstractClass ref;
}
}
// AbstractClassRunner.java /** * 抽象クラス。 */ abstract class AbstractClass { /** * 抽象メソッド。 */ abstract void printMyName(); } /** * 実行用クラス。このクラスを実行してください。 */ class AbstractClassRunner { public static void main( String[] args ) { // 抽象クラスはインスタンスを作れません! // AbstractClass ref = new AbstractClass(); // コンパイルエラー: // AbstractClassRunner.java:18: // AbstractClass は abstract です。 // インスタンスを生成することはできません。 // AbstractClass ref = new AbstractClass(); // ^ // でも参照型変数は作れます。 AbstractClass ref; } }
まずAbstractClassクラスを用意します。
* 抽象クラス。
*/
abstract class AbstractClass
{
/**
* 抽象メソッド。
*/
abstract void printMyName();
}
/** * 抽象クラス。 */ abstract class AbstractClass { /** * 抽象メソッド。 */ abstract void printMyName(); }
このクラスは抽象クラスです。
抽象クラスはインスタンスを作ることができません。
AbstractClass ref = new AbstractClass();
// コンパイルエラー:
// AbstractClassRunner.java:18:
// AbstractClass は abstract です。
// インスタンスを生成することはできません。
// AbstractClass ref = new AbstractClass();
// ^
// 抽象クラスはインスタンスを作れません! AbstractClass ref = new AbstractClass(); // コンパイルエラー: // AbstractClassRunner.java:18: // AbstractClass は abstract です。 // インスタンスを生成することはできません。 // AbstractClass ref = new AbstractClass(); // ^
このように、いつものようにnewを使用してインスタンスを作ろうとするとコンパイルエラーになります。
これは、抽象クラスは中身がないからです。
抽象クラスはprintMyName()メソッドのような抽象メソッドを持つことができます。
抽象クラスが抽象メソッドを持っていた場合に、もしインスタンスが作れてしまったら、中身のないメソッドが呼べてしまうことになります。そんなことが実際にできてしまったら、どんなことが起きるか分かりません。
それを防ぐために、抽象クラスはすべてインスタンスを作ることができないようになっています(つまり、printMyName()メソッドがなくてもコンパイルエラーになるということです)。
ただし注意して欲しいのは、参照型変数は作れるということです。
AbstractClass ref;
// でも参照型変数は作れます。 AbstractClass ref;
抽象クラスの参照型変数は作ることができます。
参照型変数はあくまで「参照の入れ物」だからです。インスタンスやメソッドとは関係ないので作ることができるというわけです。
これは、「9.1 abstractクラスとabstractメソッド」の例のような使い方ができることからも分かると思います。また逆に言えば、参照型変数は作れるので、抽象クラスを使ってポリモーフィズムができる、とも言えます。
抽象クラスは「参照型変数は作れるけど、インスタンスは作れない」ということをしっかり憶えておきましょう。