Reputation: 1078
I'm creating a website but, in order to further my coding skills, I'm trying to do it utilising the power of OOP.
I'm using classes to validate form input so thought I'd have a 'parent' validation class and then child classes for each form that gets submitted (i.e. login class, registration class etc) that would take care of putting the right values into the database etc.
The code I've seen has the parent being constructed from the child's constructor. However, I've not done that but my class seems to work anyway?
Could someone explain to me why we call the parent constructor from the child? Also, is my code only working because I have 'public' functions (methods) in my parent? (is this potentially an issue)?
My code (abridged version for clarity) is below:
class Validation_Class
{
public function __construct()
{
// constructor not needed
}
public function is_genuine_email_address($email) {
// code to validate email are genuine here...
}
}
My child class looks like...
class Login_Class extends Validation_Class
{
public function __construct()
{
// I don't call parent::__construct() from here
// should I be doing?
// I can still access parent methods with $this->is_genuine_email_address
}
}
All my functions (methods) in my Validation_Class are 'public' and when I instantiate my child class I can call any of the Validation Class methods with:
$className = "Login_Class";
$thisClass = new $className();
Upvotes: 5
Views: 1350
Reputation: 5389
Rather than using inheritance, using Strategy pattern for validation is one of the popular patterns available. This makes the code more modular and extendible,
Validating Incoming Data with the Strategy Design Pattern
Upvotes: 0
Reputation: 85538
It is not nessecary to call the parent constructor
class Parent {
//maybe just holding some constants
public $database = 'mydatabase';
}
class Child extends Parent {
public function myFunction() {
if ($this->database == 'myDatabase') {
// you can access the parents data without calling a constructor
}
}
}
Is good. But if you want to benefit from something the parent has to do itself in order to work properly, a call to the parent __construct
could be needed - like
class Parent {
public $database = null;
public function __construct() {
// example -> login to database
}
}
class Child extends Parent {
public function __construct() {
parent::__construct();
// .. further code
}
public function myFunction() {
// do something, like executing a query
$this->database->executeQuery($SQL);
}
}
In PHP "OOP", which is not real OOP like you see in other languages, constructors are just shorthands for instantiating the resulting object. It would be a hell if we over and over should call
$object = new MyClass();
$object->instantiate()
so calling __construct
or new ClassName()
is easier. But it is not absolutely needed for the class-successors to work properly, that they call constructors up in the class-hierarchy. Unless, of course, some certain initialization is needed in one of the class parents to let the successors work properly.
Upvotes: 5
Reputation: 12836
From an architecture perspective this would not make much sense. Because using OO inheritance is not just about extending a class in the code but also also designing and structuring your class hierarchy in such a way that it makes sense.
From a logic structuring stamp point I would not imagine a Login class to inherit from a validation class. Rather I might have a validation class object as a member of the Login class and use its functions to perform validations.
From inheritance perspective always remember that we should strive to have classes that represent 'Objects' and not 'Actions'. Of course we can have classes for Login and Validation actions, but actions rarely inherit in a parent-child fashion. They complement each other better an class members.
Calling a parent class, be it constructor or a standard method is not mandatory. It is required if you are having part of an action specified in the parent and more fine-grained action will be defined in the child.
The rule of the thumb is that as you traverse up an inherited class chain it becomes more and more generic and as you traverse down, it becomes more and more specialized.
Upvotes: 5