| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#71
| |||
| |||
| Hello, I agree with the quote "designers overuse inheritance as a reuse technique." One could qualify that by saying "inexperienced designers." We should not conclude that aggregation is preferable to inheritance in all contexts. Such a conclusion favors a "principle" (favor composition) over the motivation behind the principle (inheritance abuse). Not all use of inheritance is abuse. Mixins are no more susceptible to abuse that other code reuse techniques. Ask people who work in languages with good mixin support if mixins cause more problems than aggregation. The Gof book is not a bible. It represents a set of opinions at a particular point in history. At that point in time, static class diagrams (uml) were becoming popular. People often assumed they needed to create the class diagram up front, before implementing any of the leaves in the class hierarchy. Regards, Frank Hileman check out VG.net: http://www.vgdotnet.com Animated vector graphics system Integrated Visual Studio graphics editor "Richard" <legalize+jeeves@mail.xmission.com> wrote in message news:eipj94XzHHA.536@TK2MSFTNGP06.phx.gbl... > "That leads us to our second principle of object-oriented design: > > Favor object composition over class inheritance." > > So, no, they're not weaselling their way out of it by qualifying it as > public inheritance. > > They go on to say: > > "[...] our experience is that designers overuse inheritance as a > reuse technique, and designs are often made more reusable (and > simpler) by depending more on object composition." |
|
#72
| |||
| |||
| [Please do not mail me a copy of your followup] "Frank Hileman" <frankhil@no.spamming.prodigesoftware.com> spake the secret code <#MTYrUgzHHA.464@TK2MSFTNGP02.phx.gbl> thusly: >I agree with the quote "designers overuse inheritance as a reuse >technique." One could qualify that by saying "inexperienced designers." I don't know that this qualification is of much use since everyone starts out as an inexperienced designer. The problem I have seen is that people build up bad habits while inexperienced and then after having used these bad habits for a long time, they call themselves experienced, yet they are still a poor designer. >We should not conclude that aggregation is preferable to inheritance in all >contexts. That's why its a *preference* and not an outright ban on inheritance. >The Gof book is not a bible. [...] There's no reason to get insulting by bringing religion into it. -- "The Direct3D Graphics Pipeline" -- DirectX 9 draft available for download <http://www.xmission.com/~legalize/book/download/index.html> Legalize Adulthood! <http://blogs.xmission.com/legalize/> |
|
#73
| |||
| |||
| > Well, I've always heard that _public_ inheritance must be restricted to > cases of is-a. But surely there are cases when protected inheritance is > appropriate but public is not. For instance, if you are exposing a > readonly collection to your users, it may be helpful to inherit a full > featured collection privately, but make only the get accessors visible. > Sure, you could use aggregation/forwarding, but here the object is-a > readonly collection and also is-a writable collection, depending on the > user. That to me just sounds like protected inheritance. Of course, you > expose all the mutation functionality to your creator/owner by returning a > pair of pointers from a factory method, one cast to the mutable base class > and one not. > > Sadly, none of this is possible in .NET. I don't think a language should restrict a user from doing this type of thing but I personally find it extremely ugly. IMO (and it is a religious issue) an interface is something that the "public" deals with and they shoulsn't see anything else. If I use a vending machine to "download" a soft drink, I want to see the interface only - coin slot, selection buttons, change drop, etc. I don't want to see a second interface jutting out that has meaning to the manufacuter only (even if I can't use it). It's unsightly and confusing. The whole thing should be hidden which is not the case with protected or private inheritance. Your own collection example is very ugly in practice for instance (IMHO). This is because inheritance of this type isn't normally done to extend a base class' behaviour by adding extra functionality or even overriding existing behaviour. It's normally done to support a new and specifc implementation meaning your new class requires its own independent interface. A generic collection class for instance (say a "vector" that actually supported derivation) will have many different functions which become off-limits the moment I create a specific collection of type T. My new collection is designed to handle T only which usually involves very specific behaviour. It's not a "vector" from the user's standpoint and shouldn't be seen that way. It's a collection of T and that's how you want your users to see it (not as a "vector" even if it's protected/private - it still violates the "is a" relationship from their perspective). I also may not want them invoking the base class' "erase" function, "capacity" function, "reserve" function, etc. I can inherit from "vector" using "protected" or "private" and only expose what I want but users can still see it's a "vector" which is an implementation detail they shouldn't know about (especially since its functionality is off-limits). If I add my own "erase" function for instance (maybe even calling it "delete") then they'll now see two "erase" functions even if only one is accessible. The entire situation is completely unnatural and confusing notwithstanding the inconvenenience of aggregation since it requires new wrapper functions you get for free using inheritance (although even with inheritance you may need to replace a non-virtual base class function which leads to hiding issues and/or dual functions in the derived class - this can result in confusion and difficuties understanding the class even for those maintaining it). Nevertheless, I readily acknowledge that aggregation is a maintenance problem since you can wind up with many wrappers which often do little more than delegate to others (resulting in code bloat, maintenance problems, etc.). |
|
#74
| |||
| |||
| Ben, you mentioned public, private and protected inheritance. My understanding is that there is no conceivable use for protected inheritance, and, indeed, Stroustrup felt that was a mistake. ///ark |
|
#75
| |||
| |||
| "Larry Smith" <no_spam@_nospam.com> wrote in message news:ese$6wgzHHA.1184@TK2MSFTNGP04.phx.gbl... >> Well, I've always heard that _public_ inheritance must be restricted to >> cases of is-a. But surely there are cases when protected inheritance is >> appropriate but public is not. For instance, if you are exposing a >> readonly collection to your users, it may be helpful to inherit a full >> featured collection privately, but make only the get accessors visible. > >> Sure, you could use aggregation/forwarding, but here the object is-a >> readonly collection and also is-a writable collection, depending on the >> user. That to me just sounds like protected inheritance. Of course, you >> expose all the mutation functionality to your creator/owner by returning >> a pair of pointers from a factory method, one cast to the mutable base >> class and one not. >> >> Sadly, none of this is possible in .NET. > > I don't think a language should restrict a user from doing this type of > thing but I personally find it extremely ugly. IMO (and it is a religious > issue) an interface is something that the "public" deals with and they > shoulsn't see anything else. If I use a vending machine to "download" a > soft drink, I want to see the interface only - coin slot, selection > buttons, change drop, etc. I don't want to see a second interface jutting > out that has meaning to the manufacuter only (even if I can't use it). > It's unsightly and confusing. The whole thing should be hidden which is > not the case with protected or private inheritance. Your own collection > example is very ugly You were completely right... up until here. Non-public inheritance is hidden from the user. Only members can cast to a private/protected base class. > in practice for instance (IMHO). This is because inheritance of this type > isn't normally done to extend a base class' behaviour by adding extra > functionality or even overriding existing behaviour. It's normally done to > support a new and specifc implementation meaning your new class requires > its own independent interface. A generic collection class for instance > (say a "vector" that actually supported derivation) will have many > different functions which become off-limits the moment I create a specific > collection of type T. My new collection is designed to handle T only which > usually involves very specific behaviour. It's not a "vector" from the > user's standpoint and shouldn't be seen that way. It's a collection of T > and that's how you want your users to see it (not as a "vector" even if > it's That's how they would see it -- via the public interfaces it implements. > protected/private - it still violates the "is a" relationship from their > perspective). I also may not want them invoking the base class' "erase" > function, "capacity" function, "reserve" function, etc. I can inherit from > "vector" using "protected" or "private" and only expose what I want but > users can still see it's a "vector" which is an implementation detail they How? Protected/private base classes are implementation details and as such are hidden from the user. > shouldn't know about (especially since its functionality is off-limits). > If I add my own "erase" function for instance (maybe even calling it > "delete") then they'll now see two "erase" functions even if only one is > accessible. Functions in derived classes with the same name but different signatures hide base members, they do not overload. This is why. > The entire situation is completely unnatural and confusing notwithstanding > the inconvenenience of aggregation since it requires new wrapper functions > you get for free using inheritance (although even with inheritance you may > need to replace a non-virtual base class function which leads to hiding > issues and/or dual functions in the derived class - this can result in > confusion and difficuties understanding the class even for those > maintaining The using statement is a lot easier to maintain than a whole barrage of trivial forwarders. > it). Nevertheless, I readily acknowledge that aggregation is a maintenance > problem since you can wind up with many wrappers which often do little > more than delegate to others (resulting in code bloat, maintenance > problems, etc.). |
|
#76
| |||
| |||
| "Mark Wilden" <mwilden@communitymtm.com> wrote in message news:%23eIE7chzHHA.2312@TK2MSFTNGP05.phx.gbl... > Ben, you mentioned public, private and protected inheritance. My > understanding is that there is no conceivable use for protected > inheritance, and, indeed, Stroustrup felt that was a mistake. To specify the base class of a template class, where the exact class is chosen by a descendant. template <typename T> class S : protected T { }; class R : S<std::vector<Q>> { }; Naturally the class choosing the base class should have access to it, but with private inheritance, R couldn't use std::vector<Q>. |
|
#77
| |||
| |||
| Hi Richard, Sorry, I meant bible in the slang sense. GoF should not be considered a source of absolute wisdom. Frank "Richard" <legalize+jeeves@mail.xmission.com> wrote in message news:%23$$velgzHHA.5772@TK2MSFTNGP02.phx.gbl... >>The Gof book is not a bible. [...] > > There's no reason to get insulting by bringing religion into it. |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.