How to declare abstract method in non-abstract class in PHP?
Asked Answered
R

7

61
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?

Reinsure answered 3/3, 2010 at 13:16 Comment(0)
L
36

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();
}
Lisette answered 3/3, 2010 at 13:29 Comment(3)
How is this possibly the answer? The "remaining methods" in this case refers to "fuc", as the error message says, because you've declared it abstract but not declared the class itself abstract. The error message seems to be perfectly worded.Manic
@RobertGrant - if the message was perfectly worded, this question wouldn't have been asked in the first place.Incalescent
Hehe... The error message is messy, as is the reasoning of Robert above (since '"remaining methods" in this case refers to "fuc"' is the very reason why the err. msg. is confusing...), but he is still right after all: the accepted answer does not seem to answer the question. :) Is this a nice case of "circular misunderstanding", where the bogus answer solves not the bogus (see here why) question, but the actual problem the asker really had, presumably, but wrongly expressed?)Sticktight
U
82

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
    };
}
Uncinariasis answered 3/3, 2010 at 13:29 Comment(3)
Is "any class that contains at least one abstract method must also be abstract" peculiar to PHP or fairly common in OO languages?Vicinage
This is the same in F# for instanceAyurveda
@Caltor, you mean "must also be explicitly declared abstract"? Then C# is an example, too.Sticktight
L
36

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();
}
Lisette answered 3/3, 2010 at 13:29 Comment(3)
How is this possibly the answer? The "remaining methods" in this case refers to "fuc", as the error message says, because you've declared it abstract but not declared the class itself abstract. The error message seems to be perfectly worded.Manic
@RobertGrant - if the message was perfectly worded, this question wouldn't have been asked in the first place.Incalescent
Hehe... The error message is messy, as is the reasoning of Robert above (since '"remaining methods" in this case refers to "fuc"' is the very reason why the err. msg. is confusing...), but he is still right after all: the accepted answer does not seem to answer the question. :) Is this a nice case of "circular misunderstanding", where the bogus answer solves not the bogus (see here why) question, but the actual problem the asker really had, presumably, but wrongly expressed?)Sticktight
V
30

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.

Vexillum answered 3/3, 2010 at 13:16 Comment(1)
public public function bark() ?Milicent
M
4

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.

Milo answered 3/3, 2010 at 13:19 Comment(0)
M
4

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

Maybellemayberry answered 23/6, 2011 at 19:35 Comment(0)
I
3

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.

Indebtedness answered 3/3, 2010 at 13:18 Comment(0)
H
1

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

Harrumph answered 29/8, 2013 at 23:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.