Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforcing call to parent method

Is there anyway (or a pattern) to enforce a call to a parent method?

I have an abstract class like so:

abstract class APrimitive{
   public function validate(){
      //Do some stuff that applies all classes that extend APrimitive
   }
}

Then I have classes that extend upon the APrimitive "base":

class CSophisticated extends APrimitive{

   public function validate(){
       //First call the parent version:
       parent::validate();

       //Then do something more sophisticated here.
   }
}

The problem is that if we come back to the code in a few months time, and create a few more classes like CSophisticated with a validate() method, there is a possibility that we might forget to make a call to parent::validate() in that method.

Note that some CSophisticated classes may not have the validate() method, so the parent version will be called.

I understand that it is possible to just put in a comment somewhere, to remind the programmer to call parent::validate(), but is there a better way? Perhaps an automated way to throw an exception if the call to parent::validate() was not made in the validate() method would be nice.

like image 257
F21 Avatar asked Nov 04 '11 07:11

F21


People also ask

How do you call a parent method?

Calling Parent class method after method overriding Using Classname: Parent's class methods can be called by using the Parent classname. method inside the overridden method. Using Super(): Python super() function provides us the facility to refer to the parent class explicitly.

How do you call parent method from child object?

If you override a parent method in its child, child objects will always use the overridden version. But; you can use the keyword super to call the parent method, inside the body of the child method.

Can you call a parent class method from child class object?

Use of super with methods This is used when we want to call the parent class method. So whenever a parent and child class have the same-named methods then to resolve ambiguity we use the super keyword.

How do you call a parent method in C#?

Inside the Child print() method, we explicitly call the Parent print() method. This is done by prefixing the method name with “base.”.


2 Answers

You can enforce the call with the following:

abstract class APrimitive{
   final public function validate(){
      //do the logic in validate
      overrideValidate();
   }
   protected function overrideValidate(){
   }
}

class CSophisticated extends APrimitive{

   protected function overrideValidate(){

   }
}

Now only calls to validate are permitted, which will in turn call your overridden method. The syntax may be a little off (PHP is not my language of choice) but the principle is applyable to most OOP languages.

FURTHER EXPLANATION:

abstract class APrimitive{
   public function validate(){
      echo 'APrimitive validate call.';
      overrideValidate();
   }
   protected function overrideValidate(){
   }
}

class CSophisticated extends APrimitive{

   protected function overrideValidate(){
       echo 'CSophisticated call.';
   }
}

CSophisticated foo;
foo.overrideValidate(); //error - overrideValidate is protected
foo.validate(); //

Output:

APrimitive validate call.
CSophisticated call.

The function call basically does the following:

foo.validate() -> APrimitive.validate() -> ASophisticated.overrideValidate() (or APrimitive.overrideValidate() if it wasn't overriden)
like image 143
Luchian Grigore Avatar answered Oct 18 '22 15:10

Luchian Grigore


You're looking for The Template Method pattern.
This pattern allows you to modify an operation in some way through sub-classing but ensures that the base class is always involved.

class Base {
    //declared final so it can't be overridden
    public final function validate() {

        //perform base class operations here

        //then forward to the sub class
        $this->doValidate();

        //do some more base class stuff here if needed

    }

    //override this method to alter validate operation
    protected function doValidate(){
        //no-op in base
    }
}

class Sub {
    protected function doValidate() {
        //if required
        //make the sub-class contribution to validate here
    }
}
like image 21
meouw Avatar answered Oct 18 '22 14:10

meouw