6

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.

6
  • No way. Sane way. By definition you used public so you defined those methods as visible everywhere. If you want to hide parent methods from child classes, use private - but then such methods won't be seen anywhere, but that class itself. Commented Jul 18, 2014 at 9:45
  • So should I just make them protected and create another class that will call the needed protected methods? Commented Jul 18, 2014 at 9:47
  • protected isn't enough. It means visibility everywhere, including child classes. To hide method from childs, use private Commented Jul 18, 2014 at 9:48
  • I mean, I have to be able to call the methods outside. Just in this child class case I have to hide it. If I have parent object I want to be able to call the function outside the class. I think I should not be creating any instances of the parent object. Just extend it to another class and create a method that will call parent methods. Commented Jul 18, 2014 at 9:53
  • Sounds nonsensical. If one class extends another, then that class is for all intends and purposes identical to the parent class, but possibly does more or does some things different internally. But it must still be able to exactly replace the parent class in any instance where the parent class could be used. That's the Liskov substitution principle: en.wikipedia.org/wiki/SOLID. This is bad OOP design. Commented Jul 18, 2014 at 10:02

3 Answers 3

10

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)

Sign up to request clarification or add additional context in comments.

1 Comment

You've defined your method as public - and that's where you're wrong, often times we're working with code outside of our sphere of influence and have to make do.
4

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.

Comments

0

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(); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.