Code Fix

中級

Cannot instantiate abstract class の原因と直し方

abstractを付けたクラスは、そのままnewしてインスタンス化することができません。abstractクラスはサブクラスに実装させるための設計図であり、必ず継承先のクラスを使う必要があります。

エラーメッセージの読み方

Fatal error: Uncaught Error: Cannot instantiate abstract class Shape in main.php:8
main.php
ファイル名
8
行番号 — 実際にクラッシュした行
Error
例外クラス — 何が起きたか。ここを検索するのが最短です
Cannot instantiate abstract class Shape
内容 — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  <?php
 2  abstract class Shape {
 3      abstract public function area(): float;
 4  }
 5  class Circle extends Shape {
 6      public function area(): float { return 3.14; }
 7  }
 8  $s = new Shape       ();
                   ^
Fatal error: Uncaught Error: Cannot instantiate abstract class Shape in main.php:8

abstractクラスは直接newできません。areaを実装した具象クラスCircleをnewする必要があります。

直し方: Shape を Circle にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  <?php
 2  abstract class Animal {
 3      abstract public function speak(): string;
 4  }
 5  class Dog extends Animal {
 6      public function speak(): string { return "Woof"; }
 7  }
 8  $a = new Animal       ();
                   ^
 9  echo $a->speak();
Fatal error: Uncaught Error: Cannot instantiate abstract class Animal in main.php:8

Animalはabstractなのでnewできません。speakを実装したDogをnewします。

直し方: Animal を Dog にします。

この問題を解いてみる →

パターン3

 1  <?php
 2  abstract class Vehicle {
 3      abstract public function wheels(): int;
 4  }
 5  class Car extends Vehicle {
 6      public function wheels(): int { return 4; }
 7  }
 8  $v = new Vehicle       ();
                    ^
 9  echo $v->wheels();
Fatal error: Uncaught Error: Cannot instantiate abstract class Vehicle in main.php:8

Vehicleはabstractなのでインスタンスにできません。wheelsを実装したCarを使う必要があります。

直し方: Vehicle を Car にします。

この問題を解いてみる →

パターン4

 1  <?php
 2  abstract class Instrument {
 3      abstract public function play(): string;
 4  }
 5  class Piano extends Instrument {
 6      public function play(): string { return "Plink"; }
 7  }
 8  $x = new Instrument       ();
                     ^
Fatal error: Uncaught Error: Cannot instantiate abstract class Instrument in main.php:8

abstractクラスは直接newできません。playを実装した具象クラスPianoをnewする必要があります。

直し方: Instrument を Piano にします。

この問題を解いてみる →

パターン5

 1  <?php
 2  abstract class Beverage {
 3      abstract public function brew(): string;
 4  }
 5  class Coffee extends Beverage {
 6      public function brew(): string { return "Hot"; }
 7  }
 8  $b = new Beverage       ();
                    ^
 9  echo $b->brew();
Fatal error: Uncaught Error: Cannot instantiate abstract class Beverage in main.php:8

Beverageはabstractなのでnewできません。brewを実装したCoffeeをnewします。

直し方: Beverage を Coffee にします。

この問題を解いてみる →

よくある誤解

「abstractは単なる注釈で、newしても動くはず」という思い込みは誤りです。abstractクラスの直接インスタンス化は言語レベルで禁止されており、必ず致命的エラーになります。

実務での勘所

abstractクラスの直接インスタンス化が禁止されているのは、単なる注意喚起ではなく実行上の必然です。abstractクラスは中身の実装が無い(本体を持たない)抽象メソッドを持てるため、もしインスタンス化を許してしまうと、そのメソッドを呼び出した瞬間に「実行すべきコードが存在しない」という状態に陥ります。言語レベルでインスタンス化そのものを禁止することで、この矛盾が実行時に発覚するよりずっと早い、newしようとした時点で問題を検出できるようにしています。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)