Подтвердить что ты не робот

Как объявить абстрактный метод в не-абстрактном классе в PHP?

class absclass {
    abstract public function fuc();
}

сообщает:

PHP Неустранимая ошибка: класс absclass содержит 1 абстрактный метод и должен поэтому должны быть объявлены абстрактными или реализовать оставшиеся методы (Absclass:: Fuc)

Я хочу знать, что означает реализовать оставшиеся методы, как?

4b9b3361

Ответ 1

Я предполагаю, что остальные методы фактически ссылаются на абстрактные методы, которые вы пытаетесь определить (в данном случае, fuc()), так как не абстрактные методы, которые могут существовать, в любом случае в порядке. Вероятно, это сообщение об ошибке, которое могло бы использовать лучшую формулировку: там, где сказано, что она должна оставаться абстрактной.

Исправление довольно просто (эта часть сообщения об ошибке прекрасна): вам нужно изменить это:

abstract public function fuc();

... в правильную реализацию:

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

... или, в качестве альтернативы и в зависимости от ваших потребностей, сделать весь класс абстрактным:

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

Ответ 2

См. главу Абстракция класса в руководстве по PHP:

В PHP 5 представлены абстрактные классы и методы. Классы, определенные как абстрактные, не могут быть созданы, и любой класс, содержащий хотя бы один абстрактный метод, также должен быть абстрактным. Методы, определенные как абстрактные, просто объявляют подпись метода - они не могут определить реализацию.

Это означает, что вы либо должны

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
    };
}

Ответ 3

Абстрактный класс не может быть непосредственно создан, но может содержать как абстрактные, так и не абстрактные методы.

Если вы расширяете абстрактный класс, вам нужно либо реализовать все его абстрактные функции, либо сделать абзац подкласса.

Вы не можете переопределить обычный метод и сделать его абстрактным, но вы должны (в конечном итоге) переопределить все абстрактные методы и сделать их не абстрактными.

<?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 bark() ?
}

// this one succeeds in compiling, 
// it passing the buck of implementing it 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 абстрактный метод и должен поэтому должны быть объявлены абстрактными или реализовать оставшиеся методы (Собака:: коры)

Если вы закомментируете класс BadDog, то вывод будет следующим:

name: Fred
gender: female
bowowwaoar

Если вы попытаетесь создать экземпляр Dog или PassTheBuckDog напрямую, например:

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

.. он бомбит:

PHP Неустранимая ошибка: невозможно создать экземпляр абстрактный класс Собака

или (если вы закомментируете неверную строку $)

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();

Это работает отлично.

Ответ 4

Абстрактные ключевые слова используются для обозначения классов или методов в качестве шаблонов. Он похож на интерфейсы, но может содержать переменные и реализации методов.

Есть много недоразумений в отношении абстрактных классов. Вот пример абстрактного класса Dog. Если разработчик хочет создать некоторый базовый класс Dog для других разработчиков или для его расширения, он объявит класс абстрактным. Вы не можете создать экземпляр класса Dog напрямую (никто не может), но вы можете расширить Dog своим классом. SmartDog расширяет Dog и т.д.

Все методы, объявленные абстрактным классом Dog, должны быть реализованы вручную в каждом классе, который расширяет Dog.

Например, абстрактный класс Dog имеет абстрактный метод Dog:: Bark(). Но все собаки лают по-разному. Поэтому в каждом подклассе Dog вы должны описать, КАК, что собака лает конкретно, поэтому вы должны определить, например, SmartDog:: Bark().

Ответ 5

Это означает, что у собственного абстрактного класса есть хотя бы один абстрактный метод. Поэтому ваш класс должен либо реализовать метод (не абстрактный), либо быть объявленным абстрактом.

Ответ 6

Вы ошибаетесь в этом сообщении об ошибке. В этом случае, поскольку именно в этом классе определяется fuc, на самом деле не имеет смысла реализовывать его в этом классе. То, что ошибка пытается сказать вам, состоит в том, что не абстрактный класс не может иметь абстрактных методов. Как только вы поместите абстрактный метод в определение класса, вы также должны пометить сам класс как абстрактный.

Ответ 7

Я хотел использовать абстрактный метод внутри не-абстрактного класса (обычный класс?) и обнаружил, что я могу обернуть содержимое метода в операторе if if с помощью get_parent_class() следующим образом:

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() Документация