web-dev-qa-db-ja.com

PHPの非抽象クラスで抽象メソッドを宣言する方法は?

class absclass {
    abstract public function fuc();
}

レポート:

PHP致命的エラー:クラスabsclassには抽象メソッドが1つ含まれているため、抽象として宣言するか、残りのメソッドを実装する必要があります(absclass :: fuc)

残りのメソッドを実装する、どうやって?

52
user198729

残りのメソッドは、実際に定義しようとしている抽象メソッド(この場合はfuc())を参照していると推測します。 。それはおそらくより良い表現を使用できるエラーメッセージです:remainingと言うべき場所abstract

修正は非常に簡単です(エラーメッセージの一部は問題ありません)。これを変更する必要があります。

abstract public function fuc();

...適切な実装へ:

public function fuc(){
    // Code comes here
}

...または、必要に応じて、クラス全体を抽象化します:

abstract class absclass {
    abstract public function fuc();
}
30

PHPマニュアルの Class Abstractionの章を参照してください

PHP 5では、抽象クラスとメソッドが導入されています。抽象として定義されたクラスはインスタンス化できません。少なくとも1つの抽象メソッドを含むクラスも抽象である必要があります。抽象として定義されたメソッドは、メソッドの署名を宣言するだけです-実装を定義できません。

それはあなたが

abstract class absclass { // mark the entire class as abstract
    abstract public function fuc();
}

または

class absclass {
    public function fuc() { // implement the method body
        // which means it won't be abstract anymore
    };
}
77
Gordon

抽象クラスは直接インスタンス化できませんが、抽象メソッドと非抽象メソッドの両方を含めることができます。

抽象クラスを拡張する場合は、その抽象関数をすべて実装するか、サブクラスを抽象にする必要があります。

通常のメソッドをオーバーライドして抽象化することはできませんが、(最終的に)すべての抽象メソッドをオーバーライドして非抽象化する必要があります。

<?php

abstract class Dog {

    private $name = null;
    private $gender = null;

    public function __construct($name, $gender) {
        $this->name = $name;
        $this->gender = $gender;
    }

    public function getName() {return $this->name;}
    public function setName($name) {$this->name = $name;}
    public function getGender() {return $this->gender;}
    public function setGender($gender) {$this->gender = $gender;}

    abstract public function bark();

}

// non-abstract class inheritting from an abstract class - this one has to implement all inherited abstract methods.
class Daschund extends Dog {
    public function bark() {
        print "bowowwaoar" . PHP_EOL;
    }
}

// this class causes a compilation error, because it fails to implement bark().
class BadDog extends Dog {
    // boom!  where's bark() ?
}

// this one succeeds in compiling, 
// it's passing the buck of implementing it's inheritted abstract methods on to sub classes.
abstract class PassTheBuckDog extends Dog {
    // no boom. only non-abstract subclasses have to bark(). 
}

$dog = new Daschund('Fred', 'male');
$dog->setGender('female');

print "name: " . $dog->getName() . PHP_EOL;
print "gender: ". $dog->getGender() . PHP_EOL;

$dog->bark();

?>

そのプログラムは以下で爆弾します:

PHP致命的エラー:クラスBadDogには抽象メソッドが1つ含まれているため、抽象として宣言するか、残りのメソッドを実装する必要があります(Dog :: bark)

BadDogクラスをコメントアウトすると、出力は次のようになります。

name: Fred
gender: female
bowowwaoar

次のように、DogまたはPassTheBuckDogを直接インスタンス化しようとした場合:

$wrong = new Dog('somma','it');
$bad = new PassTheBuckDog('phamous','monster');

..itの爆弾:

PHP致命的エラー:抽象クラスDogをインスタンス化できません

または($ wrong行をコメントアウトした場合)

PHP致命的エラー:抽象クラスPassTheBuckDogをインスタンス化できません

ただし、抽象クラスの静的関数を呼び出すことはできます。

abstract class Dog {
    ..
    public static function getBarker($classname, $name, $gender) {
        return new $classname($name, $gender);
    }
    ..
}

..

$other_dog = Dog::getBarker('Daschund', 'Wilma', 'female');
$other_dog->bark();

それはうまく機能します。

26
Shavais

抽象キーワードは、クラスまたはメソッドにパターンとしてラベルを付けるために使用されます。インターフェイスに似ていますが、変数とメソッドの実装を含めることができます。

抽象クラスに関して多くの誤解があります。以下は、抽象的なDogクラスの例です。開発者が、他の開発者または自分で拡張するための基本的なDogクラスを作成する場合、クラスを抽象として宣言します。 Dogクラスを直接インスタンス化することはできません(誰もできません)が、独自のクラスでDogを拡張できます。 SmartDogはDogなどを拡張します。

Dogクラスによって抽象的であると宣言されているすべてのメソッドは、Dogを拡張する各クラスに手動で実装する必要があります。

たとえば、抽象クラスDogには抽象メソッドDog :: Bark()があります。しかし、すべての犬の鳴き声は異なります。したがって、各Dogサブクラスでは、犬がどのようにHえるかを具体的に記述する必要があるため、たとえばSmartDog :: Bark()を定義する必要があります。

3

これは、抽象クラスの適切なものが少なくとも1つの抽象メソッドを持っていることを意味します。したがって、クラスはメソッド(非抽象)を実装するか、抽象として宣言する必要があります。

2
instanceof me

このエラーメッセージに少し迷っています。この場合、fucが定義されているのはこのクラス内にあるため、このクラスに実装するのはあまり意味がありません。エラーがあなたに伝えようとしているのは、非抽象クラスは抽象メソッドを持つことができないということです。クラスの定義に抽象メソッドを配置するとすぐに、クラス自体を抽象としてマークする必要もあります。

2
AakashM

非抽象クラス(通常のクラス?)内で抽象メソッドを使用したいのですが、メソッドの内容をget_parent_class()を使用して 'if'ステートメントでラップできることがわかりました。

if (get_parent_class($this) !== false) {

または、アクション(cmd行のファイルでテスト済み:php -f "abstract_method_normal_class_test.php"):

<?php
    class dad {
        function dad() {
            if (get_parent_class($this) !== false) {
                // implements some logic
                echo "I'm " , get_class($this) , "\n";
            } else {
                echo "I'm " , get_class($this) , "\n";
            }
        }
    }

    class child extends dad {
        function child() {
            parent::dad();
        }
    }

    $foo = new dad();
    $bar = new child();
?>

Output:
I'm dad
I'm child

PHP get_parent_class()ドキュメント

0
Brent Self