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

PhpAbstract Function

Php Problem Overview


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?

Php Solutions


Solution 1 - Php

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

Solution 2 - Php

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

Solution 3 - Php

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.

Solution 4 - Php

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.

Solution 5 - Php

Abstract keywords are used to label classes or methods as patterns. It's similar to interfaces but can contain variables and implementations of methods.

There are a lot of misunderstandings concerning abstract classes. Here is an example of an abstract Dog class. If a developer wants to create some basic Dog class for other developers or for himself to extend he declares the class as abstract. You can't instantiate the Dog class directly (nobody can), but you can extend Dog by your own class. SmartDog extends Dog etc.

All methods that are declared to be abstract by the Dog class must be implemented manually in each class that extends Dog.

For example, the abstract class Dog has an abstract method Dog::Bark(). But all Dogs bark differently. So in each Dog-subclasses you must describe HOW that dog barks concretely, so you must define eg SmartDog::Bark().

Solution 6 - Php

It means that the proper of an abstract class is having at least one abstract method. So your class has either to implement the method (non abstract), or to be declared abstract.

Solution 7 - Php

I wanted to use an abstract method within a non-abstract class (normal class?) and found that I could wrap the method's contents in an 'if' statement with get_parent_class() like so:

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

Or, in action (tested in a file on cmd line: 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() Documentation

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser198729View Question on Stackoverflow
Solution 1 - PhpGordonView Answer on Stackoverflow
Solution 2 - PhpÁlvaro GonzálezView Answer on Stackoverflow
Solution 3 - PhpShavaisView Answer on Stackoverflow
Solution 4 - PhpAakashMView Answer on Stackoverflow
Solution 5 - PhpAlex YaroshevichView Answer on Stackoverflow
Solution 6 - Phpinstanceof meView Answer on Stackoverflow
Solution 7 - PhpBrent SelfView Answer on Stackoverflow