MB>> 1) Visibility is about information hiding not showing. Visibility is both hiding and showing. Visibility is defining what is shown and what is hidden.
MB>> 2) You are wrong about 'is-a' in general. Our main problem here is that we MB>> do not have a typecast operator. I do not see why typecast operator is needed here. MB>> 1) Visibility modifiers are for information hiding. That is you can hide MB>> certain MB>> implementation details. Each class has three interfaces: i) the interface MB>> accessible from any other scope. ii) the interface accessible from any MB>> derived class OK. MB>> Suppose you are going to design an encryption framework. Then you MB>> surely will first design an interface. In php you will create an MB>> abstract class to accomplish this. Then you will implement general MB>> features which will handle unencrypted content and such. Also you may MB>> implement general key handling. In the class hierarchy you will make MB>> all acess to uncencrypted content protected or even private starting MB>> from here. Doing this you ensure that no user and in case of private That means here you have a design flaw. If you have class EncryptionBase with *public* method foo(), and you do not want users of class EncryptionExtended to access foo(), you *should not* derive EncryptionExtended from EncryptionBase. You should use aggregation, delegation and all that stuff. Inheritance means declaring that derived class is built along all the protocols defined for base class. If you use for inheritance just as a tool to avoid copy-paste - this is wrong. I.e., it may work in the short run, but that's not intent of the OO as I see it. MB>> Or suppose you have a class for content handling and you will base MB>> encryption on top of this. Then you will derive the encryption MB>> handling from content handling and mark unencrypted acess MB>> methods/properties as private. Then, again, you should not derive encrypted content handling from unencrypted, _unless_ you are going to give access to the same methods. Generally what people do is to use same protocols (i.e, same methods), but these methods would give different result - so, BaseStream::output would output unencrypted content while EncryptedStream::output will output encrypted content, but this code: function printNumber($stream, $number) { $stream->output("This is number: $number"); } would work in any case, as long as stream is inherited from BaseStream. If you make output method hidden in derived class, you will have or to check before each call to printNumber, what stream do you have now, or get very hard-to-find errors in runtime. MB>> More examples could be made but that's not the point here. The point MB>> is that there is a need for decreasing visibility. And personally i MB>> do not see any need for increasing visibility besides the 'is_a' MB>> comment. I don't know about _increasing_ visibility, but I'm firm in opinion that _decreasing_ visibility in inheritance violates inheritance protocol and prevents people from writing OO-style code. As for increasing, I personally don't need it - you can proxy needed methods anyway - but it at least doesn't violate inheritance principles. MB>> class A { MB>> function println($msg) { MB>> echo "$msg\n"; MB>> } MB>> } MB>> class B { MB>> function println() { MB>> // whatever... MB>> } MB>> } MB>> MB>> when in this example you work on B instances with A's protocol you MB>> will see that B's println does not recognize $msg. => When deriving /* I base here on assumption that you meant B being inherited from A, otherwise there's nothing to discuss, so see all the following in this light */ The first question to ask is: why did you call the second function println? Answering this may alone bring some satori, but in case it does not, I will continue. This example is bad too, and actually if I could I would disallow this too. AFAIK, C++, which has means to do this, takes care for this by making parameters part of the function signature, so you can not do such things. I do not know if it is possible to fix this in PHP, but I clearly regard this as inheritance abuse. However, this is less important, since if you write it right - i.e., keep the protocol of println($msg) but ignore $msg - it is perfectly legitimate use of inheritance. So, I repeat, if it would be easy to prohibit such things, I would propose to do this too, but this is somewhat less important since you can live with it if it is not abused 'too much'. And yes, you can not prevent all cases of inheritance abuse, however hard you try - for example, if you write extension to class List, which overrides method getElement() to clean the list, and try to use this extension with function SortList that uses getElement(), you will discover that you are in a big trouble. To prevent people from shooting in their feet 100% is an impossible task. But we can at least not help them too much. MB>> Maybe we decide that for PHP this is not a problem since we simply MB>> ignore this fact what is possible in a loosely typed language. That has nothing to do with loose/strict typing - even in loosely typed language you cannot convert object of class X into object of class Y if there's no relation between classes. That would be just meaningless. MB>> private in B can be used with protocol A if they are public there. It MB>> does not imply that you can use A's protocol without typecasting b to MB>> A. When in this scenario all methods are linked dynamically we have Here I do not see what do you mean by 'typecasting' or why we need one. MB>> In this C++ example dynamic_cast is used for "is_a". When MB>> dynamic_cast<X*>(p) returns NULL the variable p is not of type X or MB>> one of it's parent. Well, I think futher we get from dynamic_cast<X*> and other C++ niceities, better we are. C++ has unfortunate C past and thus has all kinds of troubles with OO, but this is not the reason to copy all these troubles in PHP. -- Stanislav Malyshev, Zend Products Engineer [EMAIL PROTECTED] http://www.zend.com/ +972-3-6139665 ext.109 -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php