How to declare abstract method in non-abstract class in PHP?

class absclass {
    abstract public function fuc();
}

reports:

PHP Fatal error: Class absclass contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (absclass::fuc)

I want to know what it means by implement the remaining methods,how?


See the chapter on Class Abstraction in the PHP manual:

PHP 5 introduces abstract classes and methods. Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature - they cannot define the implementation.

It means you either have to

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

or

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

I presume that remaining methods actually refers to the abstract methods you're trying to define (in this case, fuc()), since the non-abstract methods that might exist are okay anyway. It's probably an error message that could use a more precise wording: where it says remaining it could have said abstract.

The fix is pretty straightforward (that part of the error message is fine): you need to change this:

abstract public function fuc();

... into a proper implementation:

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

... or, alternatively and depending your needs, make the whole class abstract:

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

An abstract class cannot be directly instantiated, but it can contain both abstract and non-abstract methods.

If you extend an abstract class, you have to either implement all its abstract functions, or make the subclass abstract.

You cannot override a regular method and make it abstract, but you must (eventually) override all abstract methods and make them non-abstract.

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

?>

That program bombs with:

PHP Fatal error: Class BadDog contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Dog::bark)

If you comment out the BadDog class, then the output is:

name: Fred
gender: female
bowowwaoar

If you try to instantiate a Dog or a PassTheBuckDog directly, like this:

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

..it bombs with:

PHP Fatal error: Cannot instantiate abstract class Dog

or (if you comment out the $wrong line)

PHP Fatal error: Cannot instantiate abstract class PassTheBuckDog

You can, however, call a static function of an abstract class:

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

That works just fine.


You're being slightly led astray by this error message. In this case, since it is within this class that fuc is being defined, it wouldn't really make sense to implement it in this class. What the error is trying to tell you is that a non-abstract class cannot have abstract methods. As soon as you put an abstract method in the definition of a class, you must also mark the class itself as abstract.