Anish Chandran
Anish Chandran

Reputation: 447

Abstract class method declaration

I just wrote code like this:

<?php
class test
{
// Force Extending class to define this method
abstract protected function getValue();
abstract protected function prefixValue($prefix);

// Common method
public function printOut() {
    print $this->getValue() . "\n";
}
}
class testabs extends test{

public function getValue()
{

}
public function prefixValue($f)
{

}
}
$obj = new testabs();
?>

When I run this code, I received the error below:

Fatal error: Class test contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (test::getValue, test::prefixValue) in C:\wamp64\www\study\abstract.php on line 12

I understand the first part of this error. I changed the class test to abstract and the error is gone, but the or part i can't understand.

Upvotes: 6

Views: 10900

Answers (4)

Sᴀᴍ Onᴇᴌᴀ
Sᴀᴍ Onᴇᴌᴀ

Reputation: 8297

If you are going to add abstract methods, then you will need to make the class abstract as well. That way, the class cannot be instantiated- only non-abstract sub-classes can be.

The method visibility (refer to the second sub-section Method Visiblilty) is not the same in the sub-class. Depending on whether you want the methods to be called by code outside of sub-classes, you can declare the (abstract) methods in class test with visibility public, or else declare the sub-class methods also with visibility protected.

And note the second paragraph from the Class Abstraction page, which explains this:

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private

<?php
abstract class test{
    // Force Extending class to define this method
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);

    // Common method
    public function printOut() {
        print $this->getValue() . "\n";
    }
}
class testabs extends test{

    protected function getValue()
    {

    }
    /**
    *   this method can be called from other methods with this class 
    *   or sub-classes, but not called directly by code outside of this       class
    **/
    protected function prefixValue($f)
    {

    }
}
$obj = new testabs();
// this method cannot be called here because its visibility is protected
$obj->prefixValues();// Fatal Error
?>

Upvotes: 9

Mohd Belal
Mohd Belal

Reputation: 1179

The key technical differences between an abstract class and an interface are:

  • Abstract classes can have constants, members, method stubs (methods without a body) and defined methods, whereas interfaces can only have constants and methods stubs.
  • Methods and members of an abstract class can be defined with any visibility, whereas all methods of an interface must be defined as public (they are defined public by default).
  • When inheriting an abstract class, a concrete child class must define the abstract methods, whereas an abstract class can extend another abstract class and abstract methods from the parent class don't have to be defined.
  • Similarly, an interface extending another interface is not responsible for implementing methods from the parent interface. This is because interfaces cannot define any implementation.
  • A child class can only extend a single class (abstract or concrete), whereas an interface can extend or a class can implement multiple other interfaces.
  • A child class can define abstract methods with the same or less restrictive visibility, whereas a class implementing an interface must define the methods with the exact same visibility (public).

Upvotes: 3

dave
dave

Reputation: 11975

Your class has abstract functions but is not declared as abstract, so you have two choices. Either declare the class as abstract or provide an implementation of the abstract functions.

The first option (which you tried) allows the class to exist and be used by a concrete subclass that implements the functions. The second option means that the class is fully defined and can be used as is.

Upvotes: 2

Code Spirit
Code Spirit

Reputation: 5029

When your class has abstract methods it has to be declared abstract too. So the following is correct:

<?php
abstract class test
{
  // Force Extending class to define this method
  abstract protected function getValue();
  abstract protected function prefixValue($prefix);

  // Common method
  public function printOut() {
    print $this->getValue() . "\n";
  }
}

Upvotes: 0

Related Questions