So let's say I have classes called parent and child, which will be then used from PHP file called caller.php
class Child extends Parent {
}
class Parent {
public function parentMethod(){
}
}
caller.php
PREVENTED:
$child = new Child();
$child->parentMethod();
ALLOWED:
$parent = new Parent();
$parent->parentMethod();
I want to prevent calling parentMethod like this. But if I created Parent object I want to be able to call the parentMethod. Is there some way that I can use to hide this method from being public in Child class, but still allowing parent object to call this method publicly?
Only solution I have come up with so far is making those methods protected and then creating an other class that would extend parent and then have public method for each function that it needs, but that doesn't sound very smart.
Actually, you should ask yourself: why do you need such restriction? You've defined your method as public - thus, you told PHP that it should be visible everywhere. So to prevent child calls you should use private visibility definition.
There is a way to check if call is made from parent class, like:
class ChildClass extends ParentClass {}
class ParentClass
{
public function parentMethod()
{
if(get_class($this) != __CLASS__)
{
throw new LogicException("Somehow due to business logic you're not allowed to call this from childs");
}
}
}
But I would not recommend to do that. Reasons are:
Readability. Your method is just ordinary public method. Looking to it it's impossible to say either you should use it with child calls or not. Thus, to maintain such code you'll need to check that restriction in code. Now imagine that you have ~50 methods like that. And dozen of classes like that.
Possibly, breaking Law of Demeter. Why should parent class be aware of it's childs when using such limitation?
Finally, it's just unexpected behavior. Looking to definition, anybody will see that you're extending one class by another. Thus, by definition all inherit methods with proper visibility must be inherited. And your logic changes that.
You may think about composition, not inheritance. That may be right way to implement your logic (however, I can't tell that for sure since I don't know whole background)
You can rearrange your code by adding a base parent class for both of your mentioned classes. Like so:
class Base {
public function inheritableMethod1() {}
public function inheritableMethod2() {}
}
class Child extends Base {
}
class Parent extends Base {
public function additionalMethod() {}
}
Move all inheritable methods from the Parent class to the Base, and leave there only those which must not be called on Child (the parentMethod in your example).
The base class optionally might be abstract to prevent instantiating it directly.
Check if Abstract Class suits your needs:
PHP: Class Abstraction
class Child extends Parent {
public function parentMethod(
# Code
}
}
Abstract class Parent {
abstract public function parentMethod();
}
Background
In a project with a PHP 5.6 runtime, I need to work around some third-party code. This code will not be changed by the vendor, nor will it be removed from the codebase.
Specifically, the third-party code (let's call its namespace Theirs) contains a class (\Theirs\BaseClass) whose constructor instantiates another class (\Theirs\Detector).
BaseClassTheirs.php:
<?php namespace Theirs;
class Detector {
public function __construct() {
print "Theirs\n";
}
}
class BaseClass {
public function __construct() {
$detector = new Detector();
}
}
I do not want BaseClass to instantiate \Theirs\Detector. Instead, I want BaseClass to instantiate a different Detector class, from a different namespace (Mine) that is outside of the third-party's control.
In all other respects, though, I want BaseClass to behave as it does in the third-party code, including if the vendor later adds additional functionality to \Theirs\BaseClass. (I'll call this property "non-fragility" and the lack of it "fragility".) As such, it seems sensible for me to create my own \Mine\BaseClass as a child of \Theirs\BaseClass, inheriting everything from it.
If I take the fragile, non-DRY approach of copy-pasting \Theirs\BaseClass's constructor into \Mine\BaseClass, then \Mine\Detector is instantiated, as I desired:
BaseClassMine.php:
<?php namespace Mine;
include "BaseClassTheirs.php";
class Detector {
public function __construct() {
print "Mine\n";
}
}
class BaseClass extends \Theirs\BaseClass {
public function __construct() {
$detector = new Detector();
}
}
\\ Prints "Mine"
$obj = new BaseClass();
However, if I change this into a DRY, non-fragile approach by removing the duplicated code so that \Mine\BaseClass invokes exactly the same constructor, but as inherited from its parent rather than being copy-pasted, then \Theirs\Detector gets invoked, which is not what I want:
BaseClassMine.php:
<?php namespace Mine;
include "BaseClassTheirs.php";
class Detector {
public function __construct() {
print "Mine\n";
}
}
use \Mine\Detector;
class BaseClass extends \Theirs\BaseClass {
}
\\ Prints "Theirs"
$obj = new BaseClass();
This happens regardless of whether the file contains a use \Mine\Detector; line, as above.
Question
How can I get the best of both approaches?
I.e. how can I invoke \Theirs\Baseclass's constructor from \Mine\Baseclass's constructor in order to have it invoke \Mine\Detector, as though \Theirs\Baseclass's constructor had simply been copy-pasted into \Mine\Baseclass's context, but without actually copy-pasting it and introducing the corresponding fragility?
For instance, is there a good way to use reflection or some other introspective technique to dynamically read the parent's constructor and to "paste" it at runtime into the child class?
Related but not identical questions
late static binding | without modifying parent class with static keyword
Is there any way to set a property before calling a constructor?
Please forgive the possible naivety of this question, however I am getting myself really confused. It appears that it is good practice to use dependancy injection to decouple your code so that your classes are loaded with their dependancies. PLease imagine the following where Class Foo has a dependancy of class Bar
namespace Classes;
class Foo{
protected barInstance;
public function __construct(Bar $barInstance){
$this->barInstance=$barInstance;
}
}
However if you are autoloading your classes then surely the following does the exact same thing without the need of DI?
namespace Classes;
use Classes/Bar;
class Foo{
protected barInstance;
public function __construct(){
$this->barInstance=new Bar;
}
}
Thanks to any responders.
Autoloading ensures your class is defined when you reference it. Dependency injection gives you flexibility over what instance of an object you use.
In your example, lets say your Bar class manages a database connection. And lets say you sometimes want to connect to a different database.
public function __construct(){
$this->barInstance = new Bar();
}
Now you must refactor your Foo class to handle the change because you've tightly coupled it with an instance of Bar.
public function __construct(Bar $barInstance){
$this->barInstance = $barInstance;
}
Now, without changing Foo, I can instantiate a different instance of Bar for different situations. A commonly useful example of this is in unit tests.
In both cases autoloading made sure that Bar and all of its own dependencies are are defined outside of Foo.
Take the example with a database connection.
you have
public class foo {
public function __construct(DbConnectionInterface $db) { ... }
}
public class foo2 {
public function __construct(DbConnectionInterface $db) { ... }
}
...
and so on
In your "service container" you have something like that
$db = new PdoDbConnection(); // which implements DbConnectionInterface
$service['foo'] = new foo($db);
$service['foo2'] = new foo2($db);
If tomorrow you want to use something else than pdo, then you just have to make a new connection implementing the interface and then you can change your db connection in one place
$db = new NotPdoDbConnection(); // which implements DbConnectionInterface
$service['foo'] = new foo($db);
$service['foo2'] = new foo2($db);
If you didn't use the DI, then you should have changed your new PdoConnection() to new NotPdoConnection() in all the classes using this class. But the autoload cannot help you some much in this case. As said by lsklyut his answer its two different concepts.
its a "dummy" case but you can read some interesting articles about DI
http://fabien.potencier.org/what-is-dependency-injection.html
http://www.martinfowler.com/articles/injection.html
These are two separate concepts. Autoloading will allow you to not have to include files in your scripts and allow you to separate your classes by concept. As far as dependency injection, if Bar had additional dependencies and could not simply be instantiated by using new Bar(), but rather new Bar($dep1, $dep2), then your logic to create Bar would be buried inside Foo's constructor, as well as the constructor of any other class which requires Bar. By inverting the dependency creating Bar somewhere else before injecting it, you're relieving Foo of that additional responsibility.
Autoloading and dependency injection are unrelated concepts.
The autoloader knows how to load the classes. When a simple statement like new Foo() runs, the interpreter needs to know the definition of the Foo class. If it doesn't already know it then it invokes the autoloader(s) until the class becomes available. The autoloaders know where each class is defined and include the correct file.
The dependency injection container knows how to build objects of various types. It doesn't know (and doesn't care) about class loading. It assumes that when it runs new Bar() the class Bar is already defined (or it can be autoloaded).
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();
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.
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.
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
According to the PHP manual, a class like this:
abstract class Example {}
cannot be instantiated. If I need a class without instance, e.g. for a registry pattern:
class Registry {}
// and later:
echo Registry::$someValue;
would it be considered good style to simply declare the class as abstract? If not, what are the advantages of hiding the constructor as protected method compared to an abstract class?
Rationale for asking: As far as I see it, it could a bit of feature abuse, since the manual refers to abstract classes more as like blueprints for later classes with instantiation possibility.
Update: First of all, thanks for all the answers! But many answers sound quite alike: 'You cannot instantiate an abstract class, but for a registry, why not using a singleton pattern?'
Unfortunately, that was more or less exactly a repeat of my question. What is the advantage of using a singleton pattern (a.k.a. hiding __construct()) compared to just declaring it abstract and not having to worry about that? (Like, e.g., it is a strong connotation between developers, that abstract classes are not actually used or so.)
If your class is not meant to define some super-type, it should not be declared as abstract, I'd say.
In your case, I would rather go with a class :
That defines __construct and __clone as private methods
so the class cannot be instanciated from outside
And, this way, your class could create an instance of itself
See the Singleton design pattern, about that, btw
Now, why use a Singleton, and not only static methods ? I suppose that, at least a couple of reasons can be valid :
Using a singleton means using an instance of the class ; makes it easier to transform a non-singleton class to a singleton one : only have to make __construct and __clone private, and add some getInstance method.
Using a singleton also means you have access to everything you can use with a normal instance : $this, properties, ...
Oh, a third one (not sure about that, but might have its importance) : with PHP < 5.3, you have less possibilities with static methods/data :
__callStatic has only been introduced in PHP 5.3
There is no __getStatic, __setStatic, ...
Same for a couple of other Magic methods !
Late Static Binding has only been added with PHP 5.3 ; and not having it often makes it harder, when working with static methods/classes ; especially when using inheritance.
This being said, yes, some code like this :
abstract class MyClass {
protected static $data;
public static function setA($a) {
self::$data['a'] = $a;
}
public static function getA() {
return self::$data['a'];
}
}
MyClass::setA(20);
var_dump(MyClass::getA());
Will work... But it doesn't feel quite natural... and this is a very simple example (see what I said earlier with Late Static Binding, and magic methods).
What you describe is permitted by the PHP language, but it's not the intended usage of an abstract class. I wouldn't use static methods of an abstract class.
Here's the downside of doing that: Another developer could extend your abstract class and then instantiate an object, which is what you want to avoid. Example:
class MyRegistry extends AbstractRegistry { }
$reg = new MyRegistry();
True, you only need to worry about this if you're handing off your abstract class to another developer who won't comply with your intended usage, but that's why you would make the class a singleton too. An uncooperative developer can override a private constructor:
class Registry
{
private function __construct() { }
}
class MyRegistry extends Registry
{
public function __construct() { } // change private to public
}
If you were using this class yourself, you would simply remember not to instantiate the class. Then you wouldn't need either mechanism to prevent it. So since you're designing this to be used by others, you need some way to prevent those people from circumventing your intended usage.
So I offer these two possible alternatives:
Stick with the singleton pattern and make sure the constructor is also final so no one can extend your class and change the constructor to non-private:
class Registry
{
private final function __construct() {
}
}
Make your Registry support both static and object usage:
class Registry
{
protected static $reg = null;
public static function getInstance() {
if (self::$reg === null) {
self::$reg = new Registry();
}
return self::$reg;
}
}
Then you can call Registry::getInstance() statically, or you can call new Registry() if you want an object instance.
Then you can do nifty things like store a new registry instance inside your global registry! :-)
I implemented this as part of Zend Framework, in Zend_Registry
As other guys said, you cannot instantiate an abstract class. You could use static methods in your class to prevent instantiating, but I'm not really a fan of doing so unless I have a proper reason.
I might be little bit off-topic now, but in your example you said you wanted this for Registry pattern class. What is the reason you don't want to instantiate it? Wouldn't it better to create an instance of Registry for each registry you want to use?
Something like:
class Registry {
private $_objects = array( );
public function set( $name, $object ) {
$this->_objects[ $name ] = $object;
}
public function get( $name ) {
return $this->_objects[ $name ];
}
}
I wouldn't even use Singleton in this case.
Setting a class to abstract that only defines static properties/methods won't have a real effect. You can extend the class, instantiate it, and call a method on it and it would change the static class properties. Obviously very confusing.
Abstract is also misleading. Abstract is ment to define an class that implements some functionality, but needs more behaviour (added via inheritance) to function properly. On top of that it's usually a feature that shouldn't be used with static at all. You are practically inviting programmers to use it wrong.
Short answer: A private constructor would be more expressive and fail safe.
There are patterns in OO that are common and well-recognized. Using abstract in an unconventional way may cause confusion (sorry, my some examples are in Java instead of PHP):
abstract class - a class meant to conceptualize a common ancestor, but of which actual instances are not meant to exist (e.g. shape is an abstract superclass for rectangle and triangle).
Commonly implemented by:
use abstract modifier on class to prevent direct instantiation, but allow deriving from the class
utility class - a class that does not represent an object in the solution space, but rather is a collection of useful static operations/methods, e.g. Math class in Java.
Commonly implemented by:
make class non-derivable, e.g. Java uses the final modifier on class, and
prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors)
singleton class - a class that does represent an object in the solution space, but whose instantiation is controlled or limited, often to insure there is only one instance.
Commonly implemented by:
make class non-derivable, e.g. Java uses the final modifier on class, and
prevent direct instantiation - provide no constructors and hide or disable any implicit or default constructors (and copy constructors), and
provide a specific means to acquire an instance - a static method (often getInstance()) that returns the only instance or one of the limited number of instances
abstract really is meant to indicate a "blueprint", as you call it, for class inheritance.
Registries generally follow a singleton pattern, which means they it would instantiate itself in a private variable. Defining it as abstract would prevent this from working.
I wouldnt use an abstract class. Id use something more akin to a singleton with a protected/private constructor as you suggest. There should be very few static properties other than $instance which is the actual registry instance. Recently ive become a fan of Zend Frameworks typical pattern which is something like this:
class MyRegistry {
protected static $instance = null;
public function __construct($options = null)
{
}
public static function setInstance(MyRegistry $instance)
{
self::$instance = $instance;
}
public static function getInstance()
{
if(null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
}
This way you get a singleton essentially but you can inject a configured instance to use. This is handy for testing purposes and inheritance.
The purpose of an abstract class is to define methods that are 1) meaningful to other classes and 2) not meaningful when not in the context of one of those classes.
To paraphase some of the php docs, imagine you are connecting to a database. Connecting to a database doesn't make much sense unless you have a particular kind of database to connect to. Yet connecting is something you will want to do regardless of the kind of database. Therefore, connecting can be defined in an abstract database class and inherited, and made meaningful by, say, a MYSQL class.
From your requirements, it sounds like you don't intend to do this but instead simply require a class without an instance. Whilst you could use an abstract class to enforce this behaviour, this seems hacky to me because it abuses the purpose of abstract classes. If I encounter an abstract class, I should be able to reasonably expect that this will have some abstract methods, for example, but your class will have none.
Therefore, a singleton seems like a better option.
However, if the reason you wish to have a class without an instance is simply so that you can call it anywhere then why do you even have a class at all? Why not just load every variable as a global and then you can just call it directly rather than through the class?
I think the best way to do this is to instantiate the class and then pass it around with dependency injection. If you are too lazy to do that (and fair enough if you are! Its your code, not mine.) then don't bother with the class at all.
UPDATE: It seems like you are conflicted between 2 needs: The need to do things quickly and the need to do things the right way. If you don't care about carrying a ton of global variables for the sake of saving yourself time, you will assumedly prefer using abstract over a singleton because it involves less typing. Pick which need is more important to you and stick with it.
The right way here is definitely not to use a Singleton or an abstract class and instead use dependency injection. The fast way is to have a ton of globals or an abstract class.
From my understanding, a class without instance is something you shouldn't be using in an OOP program, because the whole (and sole) purpose of classes is to serve as blueprints for new objects. The only difference between Registry::$someValue and $GLOBALS['Registry_someValue'] is that the former looks 'fancier', but neither way is really object-oriented.
So, to answer your question, you don't want a "singleton class", you want a singleton object, optionally equipped with a factory method:
class Registry
{
static $obj = null;
protected function __construct() {
...
}
static function object() {
return self::$obj ? self::$obj : self::$obj = new self;
}
}
...
Registry::object()->someValue;
Clearly abstract won't work here.
I would say it's a matter of coding habbits. When you think of an abstract class it is usually something you need to subclass in order to use. So declaring your class abstract is counter-intuitive.
Other than that is it just a matter of using self::$somevar in your methods if you make it abstract, rather than $this->somevar if you implement it as a singleton.