The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Personally, no OO development needs any levels besides public and private (acting as current protected). Everything else just makes the point of access control unclear, which helps no one. So, since we already have a keword too many, I am against any further levels, namespace or any other.

I can think of plenty of reasons why you'd want a distinction between private and protected, especially in the case where you're designing a base class that you expect others to inherit from.

I could very easily argue that you don't "need" anything other than private, because you should be doing all variable access through getters and setters. Hell, I could argue that you don't need any member variables at all.

The things exist because they're useful. If something is useful enough to make sense to a large percentage of users, then it should be considered (and weighed against possible drawbacks, development time, other ways of implementing, etc.) This is true for any feature of any language.

I can think of plenty of reasons why you'd want a distinction between private and protected, especially in the case where you're designing a base class that you expect others to inherit from.

I could very easily argue that you don't "need" anything other than private, because you should be doing all variable access through getters and setters. Hell, I could argue that you don't need any member variables at all.

You misunderstood me completely. First off, I was saying that we only need what is currently called "protected", although it would make more sense to call it "private". In other words, there is no need for the private as it is currently defined.

Second, your argument about "not needing private" makes no sense -- the setters and getters would still have to be something other than private, wouldn't they?

The main point I want to make is that there is no need for control of inheritance of properties.

Second, your argument about "not needing private" makes no sense -- the setters and getters would still have to be something other than private, wouldn't they?

The main point I want to make is that there is no need for control of inheritance of properties.

When you say "no need", how do you define that? No need as "if it wouldn't be there, nobody would miss it" or "we'd be better off without it"?

If it's the former, I agree, but many things would be "not needed" in that perspective. If it's the latter, I must disagree. Your argument is strictly an opinion and does not reflect a programmer's point of view.

I use private more than protected in some classes, and let the inherited classes access properties via setters and getters. Just as you want to hide something from the "class user code", you may also want to hide it from class's children, because: you say you need only public and protected (and call it private). Protected is for hiding the property from the "user code". But, aren't child classes also user code?

I don't want to hide any property from other developers/users. Instead, I want to reveal properties to them by making them public. (A side note: IMO, it seems that the default for most OO languages is that properties are accessible (public or package) and they have to explicitly be stated otherwise. This helps leading to thy sort of confusion.) A developer will access my classes through their interface; if he has a good reason to bypass that and use private properties directly, that's fine.

I view classes not as bunch of code, but as types. Subclassing is subtyping, and it makes sense that a subtype shares the properties of its supertype. If you really want to hide a class's properties from its own children, you have a completely different problem.

The main point I want to make is that there is no need for control of inheritance of properties.

I don't think you have demonstrated that. Just as I may wish to require public interfaces to access a property via code control (eg: getters/setters) so too a parent class may want to enforce discipline on an otherwise private member in regards to child classes. It also reserves a name in the symbol table that private methods may be refering to -- it is not nice if a child class unwittingly clobbers a control variable that is regulated by a parent class.

I sometimes like to think that private/protected/public says that there are (can be) three types of users: those that implement base/abstract object types, those that refine base objects and those that use the refined objects. Between each group there is a virtual private/public barrier producing three types of visibility in all.

That said, I find that the use-case for private members rarely shows itself in a language such as PHP, particularly if you try to practice relatively flat class hierarchies.

One more thing: the whole private/protected confusion seems to have arisen from someone not understanding the difference between classes and instances. Information hiding should hide properties from other objects, not from other classes -- and especially not from own subclasses.

Consider this:

PHP Code:

class Foo
{
private $foofoo;
// some code
}

class Bar extends Foo
{

private $barbar = 'barbar';

// of course, this is impossible even if Bar wasn't a subclass of Foo:
function baz(Foo $foo)
{
echo $foo->foofoo;
}

// another point that the information hiding is flawed
// this should not be working, but it does:
function bazbaz(Bar $barbar)
{
echo $barbar->barbar;
}

}

$foo = new Foo();
$bar = new Bar();

The current implementation of "private" prevents an object of class Bar to access it's own $foofoo, not someone elses! And if Bar absolutely, definitely must not have a $foofoo, why does it extend a Foo in the first place??? On the other hand, an object may directly access the private properties of another object of the same class. That's pervert!

One more thing: the whole private/protected confusion seems to have arisen from someone not understanding the difference between classes and instances. Information hiding should hide properties from other objects, not from other classes -- and especially not from own subclasses.

I may be misunderstading you (again ) but what are you talking about ?
You have some valid points there, but first of all sub-classing IS NOT necessarily equivalent to sub-typing ... no way. (although it is quite common)

There is a rule of good API design that says that the single most important factor that distinguishes a well-designed module from a poorly designed one is the degree to which the module hides its internal data and other implementation details from other modules.
It's called "encapsulation".

A base class can be used to provide common functionality.
A private method can be used to provide functionality that needs to be separated into its own method, but that can change in future versions of the class.
You can change in time the number and/or meaning of the parameters, or you could change the type of the returned value.

What I mean is that you could have code reuse inside your class by separating meaningfull code blocks in separate methods, but leaving them public to child classes might brake those sub-classes when you change their signature. And we all know how common refactoring is.

There is also the singleton pattern in which case, in order to really make the singleton safe, you have to make the default constructor private.

Making abstraction of Python and other similar dynamic languages which encourage public fields (PHP?), every time I read design guidelines there is always that sentence saying "you should make each class or member as inaccessible as possible".

A fine and surprising example, Berislav, it could be considered as a bug.

But I still have to agree with bonefry. A class instance and it's child class instance can be seen as two instances of different classes (polymorphism), even though the latter is also the former. The private keyword allows you to protect a property between these two objects, not classes.

Think of a "control property" that has only a getter and no setter. Allowing subclasses to overwrite it is a "trust too much" approach, IMO.

A fine and surprising example, Berislav, it could be considered as a bug.

I don't think it's a bug, I'd rather call it a design error.

Originally Posted by dbevfat

But I still have to agree with bonefry. A class instance and it's child class instance can be seen as two instances of different classes (polymorphism), even though the latter is also the former. The private keyword allows you to protect a property between these two objects, not classes.

And this is exactly what it doesn't do.

The open-close principle states that a class should be closed to access, but open for modification. In the case of PHP (and IIRC Java), "private" keyword closes a property to both -- you can't access that property in an instance of the class from another object, but you also can't access it from a subclass to modify it.

As I said, it seems to be the effect of confusing classes with objects/instances. Inheritance is too often used to resolve compositional issues -- I did it myself -- but it's a completely incorrect use. For example, in an early framework of mine, I created a FrontController class that extended an InterceptingFilter class, which gave me the features of both in a same object. However, these are two completely different objects, with different responsibilities, and I should have had a separate InterceptingFilter object as a property of the FrontController. This was the concerns would be separate, but the usage would still be simple -- just $fc->filter->doSomething() instead of $fc->doSomething().

That way InterceptingFilter would have its private properties, inaccessible by the FrontController, which would control it using its public interface.

Originally Posted by dbevfat

Think of a "control property" that has only a getter and no setter. Allowing subclasses to overwrite it is a "trust too much" approach, IMO.

No -- that's what final keyword is for.

Private and public should control only accessibility by other instances, and mot modifiability (is that a word?) by subclasses.

I think in general we are also missing a point of view that not everyone wants their code to be inherited/overrriden. Someone might publish a closed source application but release an api.

Private helps to prevent other developers from crippling the application by overwriting sensitive methods/routines/properties, etc. Private also helps code to be self documenting when working on a bigger code base, to which items should be inherited and which should not be, depending on the circumstances.

Do not forget that certain algorithms might be propritary. Formulas like calculating apr for adjustable rate mortgage is an industry trade secrect. Even realtors and banks do not know how to calculate it, they use programs to calculate it, instead. Something like that, you might want to encode and have private methods so that there is not even a hint of how it is calculated, yet while still offer the ability to calculate it.

and there are other ways to enforce/encourage certain methods/properties besides a public interface. code generation or templated classes are a viable option in some reguard.

in php, i'd rather there be a property keyword with accessor methods and regard the current properties as class fields rather than true properties.

the final keyword prevents it from being inherited, but it does not prevent it from being used in an inherited class..... to which some routines and fields should be hidden because they are specific to the base class, nothing more.

I think in general we are also missing a point of view that not everyone wants their code to be inherited/overrriden. Someone might publish a closed source application but release an api.

Aaaaarrrrrggggghhh! :'(

I apologize for yelling, but this shows a complete misunderstanding of the issue. Let's try it by example:

PHP Code:

class Foo
{
private $var = 'I am private';
}

class Bar extends Foo
{
// let's imagine for a moment that this is possible in PHP, as it should be:
private $var = 'I am modified';
}

Now, do the changes in Bar modify Foo in any way? Of course not!

So if we have a "proprietary" class Foo, we can still have Foo instances that is in no way changed. Any modifications resign in another class, in this case Bar, and Foo is in no way rendered invalid or something.

Essentially, PHP has two keywords, private and protected, which both break the open-close principle, private by closing to modification and protected by opening to access.

$x = new Bar();
$x->Calculation();
$x->getVar(); // in theory, correct me if i am wrong, but getVar() would then return 'I # am modified'; which
# if i didn't want someone to do, for that value for whatever reason, could cause
# trouble if they were not supposed to have access to it in the first place in an inherited class. now.
# if that is the case. then what if you were doing a calculation with values that
# should be only modified a certain way?

in theory, correct me if i am wrong, but getVar() would then return 'I am modified'; which if i didn't want someone to do, for that value for whatever reason, could cause trouble if they were not supposed to have access to it in the first place in an inherited class. now. if that is the case. then what if you were doing a calculation with values that should be only modified a certain way?

First of all, your example above points to the flawed object model in PHP.

Ideally, the two methods should effectively "copy" into the Bar's definition, and use the two attributes declared there. However, as private keyword prohibits their inheritance, they are inaccessible by the new class (and we don't even get the error message!), but as the methods are defined in the superclass and not overriden, we can still access them... It's the open-close principle upside down!

That being said, I am not really sure what you mean by "doing a calculation with values that should be only modified a certain way"?

Edit: OK, I reviewed your code, and I think I understand. You see, that's a problem with not seeing the difference between classes and objects. You say:

private $num = 2345.34; // should not be changed or made known unless its changed by Foo due to certain criteria.

You see, it can't be changed by Foo, because Foo is a class, not an object -- it can be changed only by an instance of Foo. And if it is private (or protected) an instance of Bar should have absolutely no access to the value of this variable in an instance of Foo.

Well, this thread has definitely pointed to me how flawed the object model of PHP really is. It might be the same in Java, which it follows, but I'm not sure. I think I'll be checking more Ruby and Python in the future.

i refer to Foo as an object of type "Foo" after instaniation. classes are the blue print of these types to which limit, supress, expand or allow, create rules for these object of various types. It just so happens that a class identifiers is also now the name of the object type. not everyone feels like typing out. this object of Type System.Foo should be the only one to call System.Foo.Calculate().

the use of Foo is subjective as anything on this forum from p.o.v. to p.o.v.

if the object model is to your distaste, you also have the option of building your own version of php. which would be interesting to follow, since i'm sure php6's success is not quite on the table.

I think the breaking of the PPP behaviour is a bug though it may very well be by design. If it is by design, then it is very curious that final is NOT supported for members but rather only for methods. So you can not control whether a child class will reimplement a private as a public. So there are access and open class issues as BL demonstrated.

For the record, I think BL has pointed out an important shortcomingins in PHP's design/implementation though I still disagree with his basic premise. There is plenty of merit to a stronger PPP implementation for both members and methods. Never-the-less, it is not a show stopper nor does it prevent anyone from making well designed classes and objects.

i refer to Foo as an object of type "Foo" after instaniation. classes are the blue print of these types to which limit, supress, expand or allow, create rules for these object of various types. It just so happens that a class identifiers is also now the name of the object type. not everyone feels like typing out. this object of Type System.Foo should be the only one to call System.Foo.Calculate().

And how many objects of type Foo there can be? Will all of them have the same value of the attribute at all times? Can the value be modified at all?

Again, objects vs. classes.

If you subclass Foo, you get a subtype of Foo. If you don't want anyone to be able to override the Calculate() algorithm in any subclasses, you declare it final.

If Calculate depends on an external value, and that value can be different in each instance, then you can make it a class attribute. If you want that it is the same for all instances of a class, then you make it a class attribute, i.e. static, but then there is no sense in not allowing subclasses to modify it. And if you just want it to be always the same, then just declare it a constant or hardcode it into the algorithm.

if the object model is to your distaste, you also have the option of building your own version of php. which would be interesting to follow, since i'm sure php6's success is not quite on the table.

I see no point in that, as there are languages with a lot better object model than PHP -- and Java is not one of them. I'll probably be looking deeper into Python and Ruby, although ideally it would all be Smalltalk and Javascript.

You've repeatedly pointed out our "confusion" in this thread. I must tell you (not in direct regard to this quoted post, but to former ones): I'm not mixing classes with objects and I'm not using class hierachy as a means of solving object compositional issues. I think that that goes for the others posting in this thread, too. I'm not even sure where you see this confusion? If anywhere, it must be the way we express ourselves, i.e. saying "Foo can't ..." while we actually mean "an object of class Foo can't ...".

If you subclass Foo, you get a subtype of Foo. If you don't want anyone to be able to override the Calculate() algorithm in any subclasses, you declare it final.

Yes, that goes well for methods, how about properties?

In the following example, how would you protect the $age property, so that children (instances of child classes) would not modify them?

Please leave aside the fact that this code is completely useless, it's only a proof of concept.

Any Person (speaking of course about any instance of Person or it's child classes) has getAge() which returns the Person's (= instance of Person class or it's child classes) age. The age is calculated by some secret NASA algorithm, which is stored in calculateAge().

The point here is, that when you're subclassing Person:
- you can't override the getAge(), so it always returns the $age property,
- you can't overwrite the calculateAge() method, that holds the algorithm for calculating the age and writes to $age property.

Now, if you use protected visibility keyword for $age, you can do this:

// later on, pass $Person to some other code that relies on getAge()
echo $Person->getAge();

With private accessibility (visibility) keyword you can't do that, because you wouldn't be able to write to the $age property! The upper FakeAgePerson would return the properly calculated age, if the keyword was private, instead of protected.

This is a rather dumb example (does it qualify for a conspiracy theory?), but the point is that you sometimes want to hide properties from your own subclasses: you don't want the instances of child classes to be able to read/write the properties that are stored in the parent's private scope.

This is a rather dumb example (does it qualify for a conspiracy theory?), but the point is that you sometimes want to hide properties from your own subclasses

Trust me, you don't. This is a nice theoretical example, but in practice there is absolutely no reason for that. This directly violates the open-close principle. And it still doesn't prevent someone to do exactly the same as in your example, as stated above.

I mean, if you really want it not to be tampered with, why allow subclassing it at all? Just declare it final and get over with it.

The point of my post was not how to do something in PHP, but how things should work. PHP5 has an obviously flawed object model, so things here work differently.

The way I see it, you thought we don't understand Class : Object relationship, while all we were trying to tell you is what I've shown in that proof of concept.

I most definitely wouldn't. In PHP, I would use protected so that it's accessible to the child.

But what if you wouldn't want to use protected?
It's a choice one should have.

And so what? This is a completely different class and a different type, with a changed interface. This is just as if you have done this:

With a very important difference: FakeAgePerson in my example is a Person, while in yours it's not. This might not be so critical in PHP, but I imagine in some other OOP language it would be more significant.

Originally Posted by BerislavLopac

Trust me, you don't. This is a nice theoretical example, but in practice there is absolutely no reason for that. This directly violates the open-close principle.

Well, I've been taught to hide and protect, and only open if neccessary: "start with private, go to protected only if there is a good reason".
I'm willing to learn as I go, but behind the private keyword lies the concept of encapsulation, which has its place.

And it still doesn't prevent someone to do exactly the same as in your example, as stated above.

How would one do exactly the same if the keyword in my example was private? How would he fake getAge() in a true subclass of Person?

I mean, if you really want it not to be tampered with, why allow subclassing it at all? Just declare it final and get over with it.

Well, that's just pushing it . You lock things to a certain degree, while providing access points to those methods/properties that are meant to be used in a subclass. Keep important properties safe, allow reading if neccessary, deny writing. Keep balance, that sort of thing.

If it is by design, then it is very curious that final is NOT supported for members but rather only for methods.

There wouldn't be much point here. If PHP was statically typed then perhaps, because you could change the type of the attribute in a subclass, but what can you change about it in PHP? Only it's value, and that's covered by const. You could change the visibility, but you can change it downwards (towards more restrictive) only anyway.