5

Javaのような他のオブジェクト指向言語では、関数をオーバーライドできます。これはimplements@overrideなどのキーワード/アノテーションを使用して可能です。

PHPでこれを行う方法はありますか?つまり、たとえば:

class myClass {
    public static function reImplmentThis() { //this method should be overriden by user
    }
}

ユーザーに独自のmyClass::reImplementThis()メソッドを実装してもらいたい。

PHPでそれを行うにはどうすればよいですか?可能であれば、オプションにすることはできますか?

つまり、ユーザーがメソッドを実装していない場合、デフォルトのメソッドを指定できますか、それともメソッドが定義されていないことを識別できますか(を使用してこれを行うことができますmethod_exists)?

4

3 に答える 3

1
<?php
abstract class Test
{
    abstract protected function test();

    protected function anotherTest() {

    }
}

class TestTest extends Test
{
    protected function test() {

    }
}

$test = new TestTest();
?>

このように、クラスTestTestは関数testをオーバーライドする必要があります。

于 2012-12-15T16:04:37.797 に答える
1

これは、いくつかの OOP の主題に触れています。

まず、親クラスで宣言されたメソッドを単純にオーバーライドすることは、継承クラスでメソッドを再宣言するのと同じくらい簡単です。

例えば:

class Person {

    public function greet(string $whom) {
        echo "hello $whom!";
    }

}

class Tommy extends Person {
    public function greet(string $whom = "everyone") {
        echo "Howdy $whom! How are you?";
    }
}

$a = new Tommy();
$a->greet('World');

// outputs:
// Howdy World! How are you?

オーバーライドするメソッドで、オーバーライドされたメソッドのロジックを再利用したい場合は、拡張クラスから親のメソッドを呼び出すだけです::

class Tommy
{
    public function greet(string $whom)
    {
        // now with more emphasis!!!
        echo parent::greet(strtoupper($whom)) . "!!!!";
    }
}

Tommy::greet()を呼び出すようになりましPerson::greet()たが、結果を変更してから返します。

注意すべきことの 1 つは、メソッドのオーバーライドは、オーバーライドされたメソッドと互換性がなければならないということです。メソッドの可視性は、元のメソッドよりも制限的であってはならず (可視性を高めても問題ありません)、必要な引数の数と型が競合することはできません。オリジナルデカール付。

引数の型が元の型と衝突せず、親よりも必要な引数が少ないため、これは機能します。

class Leo extends Person {
    public function greet(string $whom = "gorgeous", string $greet = "Whatsup" ) {
        echo "$greet $whom. How are you?";
    }
}

しかし、追加の必須引数があるため、これはそうではありません。これにより、このクラスの元のクラスを透過的に切り替えることができなくなり、次のようにスローされますWarning


class BadBob extends Person {
    public function greet(string $whom, string $greet ) {
        echo "$greet $whom. How are you?";
    }
}

さらに、質問で「このメソッドはユーザーがオーバーライドする必要がある」と述べています。メソッドを実際に実装するクライアント クラスが必要な場合は、いくつかのオプションがあります。

抽象クラスとメソッド

これらは、実装が空のままであり、拡張クラス有効になるために実装する必要があるメソッドです。では、元のクラスPersonを次のように変更しました。

abstract class Person {

    public function greet(string $whom) {
        echo "hello $whom!";
    }

    public abstract function hide();

}
  • クラスには抽象メソッドが含まれているため、抽象クラスとしても宣言する必要があります。
  • 現在、Person直接インスタンス化することはできません。他のクラスでのみ拡張できます。
  • これで、既存のPerson拡張クラスはすべて正しくなくなり、前のコードを実行しようとすると致命的なエラーがスローされます。

Person現在拡張されている有効なクラスの例は次のとおりです。

class Archie extends Person {

    public function hide() {
        echo "Hides behind a bush";
    }
}

拡張するすべてのクラスは、パブリックメソッドを宣言するPerson 必要があります。hide()

インターフェース

最後に、インターフェースについて言及します。インターフェイスは、実装クラスが満たす必要がある契約です。実装本体なしでパブリック メソッドのグループを宣言します。

例えば:


interface Policeman {
    public function arrest(Person $person) : bool;
        
    public function help($what): bool;
}

Personこれで、拡張および実装されたクラスを作成できますPoliceman

class Jane extends Person implements Policeman {
    
    public function hide() {
        echo "Jane hides in her patrol-car";
    }
    
    public function arrest(Person $person): bool{
        // implement arrest method
        
        return false;
    }
    
    public function shoot($what): bool {
        // implements shoot() method
        
        return false;
    }
}

重要なのは、拡張できるクラスは1 つだけですが (PHP には多重継承はありません)、複数のインターフェースを実装することは可能であり、クラスが有効であるためにはそれぞれの要件を満たす必要があります。

于 2019-03-02T11:22:21.757 に答える
0

はいあります。クラスを拡張し、基本クラスにあった同じ名前、関数シグネチャ、およびアクセス指定子 (public または protected) でメソッドを定義することにより、メソッドをオーバーライドするオプションがあります。メソッドを基本クラスで抽象宣言しないでください。そうしないと、派生クラスで実装する必要があります。あなたの例では、次のようになります。

class MyClass {
    public static function reImplmentThis() { //this method should be overriden by user
    }
}

class MyDerivedClass extends MyClass {
    public static function reImplmentThis() { //the method you want to call
    }
}

ユーザーがオーバーライドしない場合、MyDerivedClass には、MyClass から継承された reImplmentThis() メソッドが引き続き含まれます。

とはいえ、派生クラスから拡張された静的メソッドを呼び出すときは、トラブルを避けるために細心の注意を払う必要があります。静的クラスを拡張する必要が特にない限り、コードをリファクタリングしてインスタンス メソッドを拡張することをお勧めします。また、静的クラスを拡張するよりも良い方法はないと判断した場合は、 Late Static Bindingを十分に理解してください。

はい、メソッドが実装されているかどうかを確認し、 PHP Reflectionを使用してクラスに関するより多くの情報を取得することができます。

于 2015-12-10T18:31:46.547 に答える