PHPで抽象クラスの静的メソッドから子クラスのインスタンスを生成する方法
抽象クラス(abstract class)内に定義した静的メソッドから、その子クラス自身のインスタンスを生成したい場合があります。このようなケースでは、self の代わりに new static() を使用するのがポイントです。
new static() は「遅延静的束縛(Late Static Bindings)」と呼ばれる仕組みで、実際に呼び出されたクラス(ここでは子クラス)のインスタンスを返します。new self() を使うと常に定義元の親クラスが対象になってしまうため、注意が必要です。
実装例
以下に、抽象クラス Base の静的メソッドから子クラス Child のインスタンスを生成し、抽象メソッドを呼び出すサンプルコードを示します。
<!DOCTYPE html>
<html>
<body>
<?php
abstract class Base{
protected static $fullName = '';
abstract protected function customFunction();
public static function get_obj($param1 = null, $param2 = null){
$obj = new static();
$obj->customFunction();
}
public static function getFullName(){
return static::$fullName;
}
}
class Child extends Base {
protected static $fullName = 'John Doe';
protected function customFunction(){
echo self::getFullName() . "<br>";
echo $this;
}
}
Child::get_obj();
?>
</body>
</html>実行結果
このコードを実行すると、次のような出力が得られます。
John Doe
コードの解説
new static() の役割
静的メソッド get_obj() 内の new static() は、呼び出し元である Child クラスのインスタンスを生成します。これにより、抽象クラス側のコードを変更することなく、各子クラスごとのオブジェクトを柔軟に作成できます。
static:: によるプロパティ参照
getFullName() メソッドでは static::$fullName を使用しています。これも遅延静的束縛によるもので、子クラスで上書きされた $fullName(この例では「John Doe」)が正しく参照されます。仮に self::$fullName と記述すると、親クラス側の空文字が返されてしまいます。
抽象メソッドの呼び出し
生成したインスタンスに対して $obj->customFunction() を呼び出すことで、子クラスで実装された具象メソッドが実行されます。このパターンは、ファクトリメソッドとして抽象クラスに共通のインスタンス生成処理を持たせたい場合に特に有効です。
-
C#のvirtual・sealed・new・abstractキーワードの違いを徹底解説
はじめにC#には、継承やポリモーフィズムに関わる重要なキーワードとして「virtual」「sealed」「new」「abstract」があります。それぞれ役割が大きく異なるため、正しく理解して使い分けることが、保守性の高いコードを書くための第一歩となります。この記事では、各キーワードの特徴と使い方をコード例とともに解説します。virtual:メソッドのオーバーライドを許可するvirtual キーワードを付けたメソッドは、派生クラスでのオーバーライド(上書き)が可能になります。親クラスのメソッドを子クラスで再定義したい場合は、親クラス側のメソッドを virtual として宣言しておく必要がありま
-
Pythonの静的メソッド(@staticmethod)とは?仕組みと使い方を解説
Pythonのクラスには、インスタンスメソッド、クラスメソッド、静的メソッド(スタティックメソッド)という3種類のメソッドを定義できます。それぞれ役割や呼び出し方が異なり、適切に使い分けることでコードの可読性と保守性が向上します。3種類のメソッドの違いインスタンスメソッド: 第1引数に self を受け取り、オブジェクト(インスタンス)の状態にアクセス・変更できます。クラスメソッド: @classmethod デコレータを付け、第1引数に cls を受け取り、クラス自体の状態にアクセスできます。静的メソッド: @staticmethod デコレータを付け、self も cls も受け取りません