13

From some brief fiddling about, I find I get an error when overriding superclass methods in a subclass when I do the following:

  • Override a protected superclass method with a private subclass method
  • Override a public superclass method with a protected or private subclass method

However, If I do it in the other direction, no error is thrown:

  • Overriding a private superclass method with a protected or public subclass method
  • Overriding a protected superclass method with a public subclass method

This seems counter intuitive to me - I was expecting it to work the other way around in order to enforce information hiding and encapsulation. This appears to allow poor design by allowing internals to be exposed in a way that may break other methods and I can't see a case when this would be a good idea. Why has it been implemented this way and what have I missed?

Also, is this standard practice in other programming languages?

Matt Gibson
  • 14,616
  • 7
  • 47
  • 79
  • I mean that in order to prevent dependencies from developing between components, it's good to stick to just the minimum number of exposed public methods. Allowing private methods to be made public encourages other devs to make use of them and therefore undermines the ability to swap out classes using polymorphism. – Matt Gibson Feb 21 '12 at 12:43
  • 1
    Correct me if I'm wrong: the programming language is to be a tool and should be flexible as it possible; design of code, patterns and behaviors are on the conscience of the developer. Now, if we imagine that you are not talking about outside vulnerabilities, are you really talking about programmers from one team sabotaging the development? – YuS Feb 21 '12 at 12:50
  • Well, to be as flexible as possible it would not have public/private/protected at all :) What I'm really asking is 'why is it necessary to sometimes make private things public' as I can't envisage a use case where it would help. On the other hand, I'm sure there must be one sometimes or else it would throw an error in order to help enforce good design as per the decision to include public/private/protected. Or so I assume. – Matt Gibson Feb 21 '12 at 12:54
  • 1
    you cannot make a private method public. They will be two _different_ methods. – KingCrunch Feb 22 '12 at 07:28
  • 1
    Basically, you can add to a subclass, but not take away from it. – Jonathon Mar 11 '13 at 18:26
  • for me it's really ugly. you have to check your code if you can overwrite this function. because if you have a super that implements an interface where the function is protected or private you can not redeclare it as public... why I should be able to do it when there is no interface and of course why at all? – iRaS Aug 24 '16 at 20:44

4 Answers4

17

What you call "enforce information hiding" is something, that may break subclasses, because suddenly properties and methods may disappear. You cannot break things by loosing restrictions this way.

With private is a bit different: In this case the property/method does not exists from the child class' point of view. Thus there is no reason, why a subclass may not introduce a property with that name, because it will be a different property.

You are right, that this may lead to poor design, but you can always build an application with poor design.

int3
  • 12,861
  • 8
  • 51
  • 80
KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • hm I agree to matt. this does not make sense. for me there should only be a script way: every sublcass has to respect the visibility of properties from the superclass (in every direction). – iRaS Aug 24 '16 at 20:40
  • @iRaS what you are missing is that private properties/methods are not about "information hiding" at all, but about preventing behavior from being overridden or affected by a child class. If you create a new private/public method in a child class that has the same name as a private method in the parent class, the parent class won't call that method (unless it uses late static binding to call it) – Omn Jan 22 '18 at 18:40
11

You can't decrease the visibility of class members, only increase them.

Imagine a class A which has a public method, and a subclass B would make it private. B could be treated as a type A, for which it is assumed that it has that public method.

fivedigit
  • 18,464
  • 6
  • 54
  • 58
  • Yes, I see what you mean, but if you do it the other way surely a similar problem emerges: your code becomes dependent on a function that B has exposed, which A still declares as private? I suppose I'm arguing that public and private/protected should not be interchangeable via inheritance. – Matt Gibson Feb 21 '12 at 12:46
  • It might break encapsulation indeed. I personally don't often do this, if ever. But it still wouldn't affect A, since A should be treated as A, not B. It's indeed not the best design possible I'd say. – fivedigit Feb 21 '12 at 12:52
0

If you think expossing a private/protected method in a subclass represents a problem, just make the method final.

See it this way: by NOT making a method final, you are allowing any subclass to overriding it at will; this obviously includes increasing its visibility.

0

If a superclass exposes a method publicly, then all its subclasses must also expose the same method (or an overridden version), therefore reducing the accessibility of a method is a subclass is illegal in PHP (and pretty much every class-based OO language).

The opposite is not true, so increasing the accessibility of methods in subclasses is perfectly fine.

GordonM
  • 31,179
  • 15
  • 87
  • 129