By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,970 Members | 1,193 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,970 IT Pros & Developers. It's quick & easy.

Strange question: why can't some classes be inherited?

P: n/a
I just discovered that the ImageList class can't be inherited. Why? What
could go wrong? I can invision a case where someone would like to add, say,
an ID field to an ImageList, possible so that the individual elements in an
array of ImageList's could be identified by the ID, thereby allowing
re-ordering the array without harm. A person could identify by index into
the array, but that would not be preserved by re-ordering (and re-ordering
makes sense if one removes one of the ImageList's in the array). But without
the ability to inherit ImageList, now one must design a new a class with an
ImageList member and an ID member. This wouldn't be a big deal, but now to
expose the public methods of the contained ImageList one must either expose
the member itself or manually expose the various innate features of an
ImageList. This is done automatically if one is allowed to inherit ImageList
in a 'public' way.

Now that's just an exampe with ImageList, and ID is not a good example, I
just used it to make my point. In general, it seems odd one would want to
prevent any class from being inherited. I can see preventing the overriding
or overloading of some class methods and keeping some members private. But
complete denial? Why?

[==P==]
Dec 1 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
JAL
Peter.... I can't speak to the ImageList example, but Snyder has argued that
if a class was not designed to be extended it should be sealed. The reason is
that "inheritance breaks encapsultation." You can still use composition as in
Joshua Blocks "prefer composition over inheritance".

"Peter Oliphant" wrote:
I just discovered that the ImageList class can't be inherited. Why? What
could go wrong? I can invision a case where someone would like to add, say,
an ID field to an ImageList, possible so that the individual elements in an
array of ImageList's could be identified by the ID, thereby allowing
re-ordering the array without harm. A person could identify by index into
the array, but that would not be preserved by re-ordering (and re-ordering
makes sense if one removes one of the ImageList's in the array). But without
the ability to inherit ImageList, now one must design a new a class with an
ImageList member and an ID member. This wouldn't be a big deal, but now to
expose the public methods of the contained ImageList one must either expose
the member itself or manually expose the various innate features of an
ImageList. This is done automatically if one is allowed to inherit ImageList
in a 'public' way.

Now that's just an exampe with ImageList, and ID is not a good example, I
just used it to make my point. In general, it seems odd one would want to
prevent any class from being inherited. I can see preventing the overriding
or overloading of some class methods and keeping some members private. But
complete denial? Why?

[==P==]

Dec 2 '05 #2

P: n/a
Inheritance can't break encapsulation if encapsulation is done correctly.
That's what 'private' vs. 'protected' and 'virtual' vs. 'non-virtual' are
all about (at least I thought so)...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:B0**********************************@microsof t.com...
Peter.... I can't speak to the ImageList example, but Snyder has argued
that
if a class was not designed to be extended it should be sealed. The reason
is
that "inheritance breaks encapsultation." You can still use composition as
in
Joshua Blocks "prefer composition over inheritance".

"Peter Oliphant" wrote:
I just discovered that the ImageList class can't be inherited. Why? What
could go wrong? I can invision a case where someone would like to add,
say,
an ID field to an ImageList, possible so that the individual elements in
an
array of ImageList's could be identified by the ID, thereby allowing
re-ordering the array without harm. A person could identify by index into
the array, but that would not be preserved by re-ordering (and
re-ordering
makes sense if one removes one of the ImageList's in the array). But
without
the ability to inherit ImageList, now one must design a new a class with
an
ImageList member and an ID member. This wouldn't be a big deal, but now
to
expose the public methods of the contained ImageList one must either
expose
the member itself or manually expose the various innate features of an
ImageList. This is done automatically if one is allowed to inherit
ImageList
in a 'public' way.

Now that's just an exampe with ImageList, and ID is not a good example, I
just used it to make my point. In general, it seems odd one would want to
prevent any class from being inherited. I can see preventing the
overriding
or overloading of some class methods and keeping some members private.
But
complete denial? Why?

[==P==]

Dec 2 '05 #3

P: n/a
Hey! What happened to my original post (the one that started this thread)?
From my POV it seems to have disappeared...

[==P==]

"Peter Oliphant" <po*******@RoundTripInc.com> wrote in message
news:ea**************@TK2MSFTNGP10.phx.gbl...
Inheritance can't break encapsulation if encapsulation is done correctly.
That's what 'private' vs. 'protected' and 'virtual' vs. 'non-virtual' are
all about (at least I thought so)...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:B0**********************************@microsof t.com...
Peter.... I can't speak to the ImageList example, but Snyder has argued
that
if a class was not designed to be extended it should be sealed. The
reason is
that "inheritance breaks encapsultation." You can still use composition
as in
Joshua Blocks "prefer composition over inheritance".

"Peter Oliphant" wrote:
I just discovered that the ImageList class can't be inherited. Why? What
could go wrong? I can invision a case where someone would like to add,
say,
an ID field to an ImageList, possible so that the individual elements in
an
array of ImageList's could be identified by the ID, thereby allowing
re-ordering the array without harm. A person could identify by index
into
the array, but that would not be preserved by re-ordering (and
re-ordering
makes sense if one removes one of the ImageList's in the array). But
without
the ability to inherit ImageList, now one must design a new a class with
an
ImageList member and an ID member. This wouldn't be a big deal, but now
to
expose the public methods of the contained ImageList one must either
expose
the member itself or manually expose the various innate features of an
ImageList. This is done automatically if one is allowed to inherit
ImageList
in a 'public' way.

Now that's just an exampe with ImageList, and ID is not a good example,
I
just used it to make my point. In general, it seems odd one would want
to
prevent any class from being inherited. I can see preventing the
overriding
or overloading of some class methods and keeping some members private.
But
complete denial? Why?

[==P==]


Dec 2 '05 #4

P: n/a
JAL
Peter.... If you specifically design a class for inheritance as in
CollectionBase, I see no problem. Here is the paper:

http://72.14.203.104/search?q=cache:...sulation&hl=en

"Peter Oliphant" wrote:
Inheritance can't break encapsulation if encapsulation is done correctly.
That's what 'private' vs. 'protected' and 'virtual' vs. 'non-virtual' are
all about (at least I thought so)...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:B0**********************************@microsof t.com...
Peter.... I can't speak to the ImageList example, but Snyder has argued
that
if a class was not designed to be extended it should be sealed. The reason
is
that "inheritance breaks encapsultation." You can still use composition as
in
Joshua Blocks "prefer composition over inheritance".

"Peter Oliphant" wrote:
I just discovered that the ImageList class can't be inherited. Why? What
could go wrong? I can invision a case where someone would like to add,
say,
an ID field to an ImageList, possible so that the individual elements in
an
array of ImageList's could be identified by the ID, thereby allowing
re-ordering the array without harm. A person could identify by index into
the array, but that would not be preserved by re-ordering (and
re-ordering
makes sense if one removes one of the ImageList's in the array). But
without
the ability to inherit ImageList, now one must design a new a class with
an
ImageList member and an ID member. This wouldn't be a big deal, but now
to
expose the public methods of the contained ImageList one must either
expose
the member itself or manually expose the various innate features of an
ImageList. This is done automatically if one is allowed to inherit
ImageList
in a 'public' way.

Now that's just an exampe with ImageList, and ID is not a good example, I
just used it to make my point. In general, it seems odd one would want to
prevent any class from being inherited. I can see preventing the
overriding
or overloading of some class methods and keeping some members private.
But
complete denial? Why?

[==P==]


Dec 2 '05 #5

P: n/a
Hi JAL,

Yes, but the question I asked is WHY would someone want to design a
completely sealed class? In what SPECIFIC scenario would it be 'dangerous'
to allow a class to be inherited, and WHY would it be dangerous in that
scenario? In describing why it would be dangerous, please say why 'private'
and not creating virtual methods are insufficient tools to cause the class
to be 'sealed enough'? That is, if I make all the public methods non-virtual
and everthing else private, where is the harm of allowing inheritance from
such a class (in contrast to sealing it)?

---

I've read parts of the article you pointed to (but not all of it). First, it
was written 19 years ago, and things have changed! Next, the article seems a
bit 'strawman' in its arguments.

For example, it uses the construction of two classes, 'stack' and 'deque'
for illustrative purposes. Quickly, a 'deque' is a 'stack' that can 'put'
and 'get' elements to/from both ends, while 'stack's can only do this at one
end. The author then says that 'stack' should inherit from 'deque' (!!!!),
that to do this the access to the methods to deal with the 'other end'
should be suppressed in 'stack', and then says this shows inheritance
weakens encapsulation since one should never remove the external interface
to the base class (i.e., derived classes should preserve the base class
interface, which I totally agree with).

But, he has it backwards. 'Deque' should inherit from 'stack' and ADD the
'back-end' functionality! IMHO, it's good programming practice to have base
classes only contain methods which apply to EVERYTHING that can derive from
it, since like the author and I do agree upon (and bears repeating),
"derived classes should preserve the base class interface". Thus, in the
author's example, he made a poor choice in 'deque' as a bases class if he
wanted to derive 'stack' from it.

The author also seems to think that derived classes have access to
everything in its base class - was this article written before 'private' was
invented? Here is a quote from the article that definitely seems to indicate
'private' was not in the author's knowledge base:

"In most obect-oriented languages, tile code of a class may directly access
all the instance variables of its objects, even those instance variables
that were defined by the ancestor class. Thus, the designer of a class is
allowed full access to the representation defined by the ancestor class."

And if a base method is NOT declared as virtual, it is sealed as far as any
derived class is concerned (at least as far as it's particular calling
sequence is defined, overloads are really new methods that just happen to
have the same name for convenience). To me 'sealed' seems like a lazy way
allowing the covering up of poor design choices when it comes to heirarchial
structure, and are usually caused by incorrectly encapsulating members and
methods via the use of 'private', and incorrect use of 'virtual'.

So, IMHO, this article does not convince me that any class should ever be
'sealed' (that is, prevented from being derived from). Ok, MAYBE a class
designed for SECURITY (e.g., DES algorithm), but I'd have to think about
that as well...
---

Now, if the new 'dialect' of C++ introduced with VS C++.NET 2005 has
included tools that allow violation of 'private', then the problem lies in
these new tools, not the concept of inheritance vs. encapsulation...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:70**********************************@microsof t.com...
Peter.... If you specifically design a class for inheritance as in
CollectionBase, I see no problem. Here is the paper:

http://72.14.203.104/search?q=cache:...sulation&hl=en

"Peter Oliphant" wrote:
Inheritance can't break encapsulation if encapsulation is done correctly.
That's what 'private' vs. 'protected' and 'virtual' vs. 'non-virtual'
are
all about (at least I thought so)...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:B0**********************************@microsof t.com...
> Peter.... I can't speak to the ImageList example, but Snyder has argued
> that
> if a class was not designed to be extended it should be sealed. The
> reason
> is
> that "inheritance breaks encapsultation." You can still use composition
> as
> in
> Joshua Blocks "prefer composition over inheritance".
>
> "Peter Oliphant" wrote:
>
>> I just discovered that the ImageList class can't be inherited. Why?
>> What
>> could go wrong? I can invision a case where someone would like to add,
>> say,
>> an ID field to an ImageList, possible so that the individual elements
>> in
>> an
>> array of ImageList's could be identified by the ID, thereby allowing
>> re-ordering the array without harm. A person could identify by index
>> into
>> the array, but that would not be preserved by re-ordering (and
>> re-ordering
>> makes sense if one removes one of the ImageList's in the array). But
>> without
>> the ability to inherit ImageList, now one must design a new a class
>> with
>> an
>> ImageList member and an ID member. This wouldn't be a big deal, but
>> now
>> to
>> expose the public methods of the contained ImageList one must either
>> expose
>> the member itself or manually expose the various innate features of an
>> ImageList. This is done automatically if one is allowed to inherit
>> ImageList
>> in a 'public' way.
>>
>> Now that's just an exampe with ImageList, and ID is not a good
>> example, I
>> just used it to make my point. In general, it seems odd one would want
>> to
>> prevent any class from being inherited. I can see preventing the
>> overriding
>> or overloading of some class methods and keeping some members private.
>> But
>> complete denial? Why?
>>
>> [==P==]
>>
>>
>>


Dec 2 '05 #6

P: n/a
JAL
Peter.... The answer to this question takes about ten pages. Here is the
actual design guideline:

"The best solution to this problem is to prohibit subclassing in classes
that are not designed and documented to be safely subclassed" Joshua Block...

Now how to get there from here:)

First IMHO Snyder is correct in that inheritance breaks encapsulation simply
if any member is non private or any method is virtual. If you do _not_ want
to provide for inheritance then you can at a minimum declare members private
and methods non virtual. But even then there is "new". In C++/CLI I believe
all methods are non virtual by default and members are private by default in
keeping with this "progressive" thinking. Contrast this to Java's package
level member accesability and by default virtual methods.

Inheritance adds fragility. So if I have a non type safe collection and I
extend it to a type safe collection, what happens when there is a new version
of the base class with a new set of non type safe accessors? My type safe
collection is no longer type safe! Instead, wrap say an arraylist in a
wrapper class that implements type safe accessors. It does not matter if a
new accessor is added to arraylist since it will _not_ be visible from my
wrapper class. This is not a problem with collectionbase since it was
designed for this and so we rely on the class programmers not to do something
like this. So, unless a class is designed for inheritance, prefer composition
over inheritance.

Inheritance can be abused so that the subclass does not respect all of the
behaviors of the base class and violates the Liskov substitution principle,
usually by throwing a not supported exception at runtime, ouch!

So it is harder to write a class designed to be extended. So some would
argue that classes should be sealed by default.

"Peter Oliphant" wrote:
Hi JAL,

Yes, but the question I asked is WHY would someone want to design a
completely sealed class? In what SPECIFIC scenario would it be 'dangerous'
to allow a class to be inherited, and WHY would it be dangerous in that
scenario? In describing why it would be dangerous, please say why 'private'
and not creating virtual methods are insufficient tools to cause the class
to be 'sealed enough'? That is, if I make all the public methods non-virtual
and everthing else private, where is the harm of allowing inheritance from
such a class (in contrast to sealing it)?

---

I've read parts of the article you pointed to (but not all of it). First, it
was written 19 years ago, and things have changed! Next, the article seems a
bit 'strawman' in its arguments.

For example, it uses the construction of two classes, 'stack' and 'deque'
for illustrative purposes. Quickly, a 'deque' is a 'stack' that can 'put'
and 'get' elements to/from both ends, while 'stack's can only do this at one
end. The author then says that 'stack' should inherit from 'deque' (!!!!),
that to do this the access to the methods to deal with the 'other end'
should be suppressed in 'stack', and then says this shows inheritance
weakens encapsulation since one should never remove the external interface
to the base class (i.e., derived classes should preserve the base class
interface, which I totally agree with).

But, he has it backwards. 'Deque' should inherit from 'stack' and ADD the
'back-end' functionality! IMHO, it's good programming practice to have base
classes only contain methods which apply to EVERYTHING that can derive from
it, since like the author and I do agree upon (and bears repeating),
"derived classes should preserve the base class interface". Thus, in the
author's example, he made a poor choice in 'deque' as a bases class if he
wanted to derive 'stack' from it.

The author also seems to think that derived classes have access to
everything in its base class - was this article written before 'private' was
invented? Here is a quote from the article that definitely seems to indicate
'private' was not in the author's knowledge base:

"In most obect-oriented languages, tile code of a class may directly access
all the instance variables of its objects, even those instance variables
that were defined by the ancestor class. Thus, the designer of a class is
allowed full access to the representation defined by the ancestor class."

And if a base method is NOT declared as virtual, it is sealed as far as any
derived class is concerned (at least as far as it's particular calling
sequence is defined, overloads are really new methods that just happen to
have the same name for convenience). To me 'sealed' seems like a lazy way
allowing the covering up of poor design choices when it comes to heirarchial
structure, and are usually caused by incorrectly encapsulating members and
methods via the use of 'private', and incorrect use of 'virtual'.

So, IMHO, this article does not convince me that any class should ever be
'sealed' (that is, prevented from being derived from). Ok, MAYBE a class
designed for SECURITY (e.g., DES algorithm), but I'd have to think about
that as well...
---

Now, if the new 'dialect' of C++ introduced with VS C++.NET 2005 has
included tools that allow violation of 'private', then the problem lies in
these new tools, not the concept of inheritance vs. encapsulation...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:70**********************************@microsof t.com...
Peter.... If you specifically design a class for inheritance as in
CollectionBase, I see no problem. Here is the paper:

http://72.14.203.104/search?q=cache:...sulation&hl=en

"Peter Oliphant" wrote:
Inheritance can't break encapsulation if encapsulation is done correctly.
That's what 'private' vs. 'protected' and 'virtual' vs. 'non-virtual'
are
all about (at least I thought so)...

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:B0**********************************@microsof t.com...
> Peter.... I can't speak to the ImageList example, but Snyder has argued
> that
> if a class was not designed to be extended it should be sealed. The
> reason
> is
> that "inheritance breaks encapsultation." You can still use composition
> as
> in
> Joshua Blocks "prefer composition over inheritance".
>
> "Peter Oliphant" wrote:
>
>> I just discovered that the ImageList class can't be inherited. Why?
>> What
>> could go wrong? I can invision a case where someone would like to add,
>> say,
>> an ID field to an ImageList, possible so that the individual elements
>> in
>> an
>> array of ImageList's could be identified by the ID, thereby allowing
>> re-ordering the array without harm. A person could identify by index
>> into
>> the array, but that would not be preserved by re-ordering (and
>> re-ordering
>> makes sense if one removes one of the ImageList's in the array). But
>> without
>> the ability to inherit ImageList, now one must design a new a class
>> with
>> an
>> ImageList member and an ID member. This wouldn't be a big deal, but
>> now
>> to
>> expose the public methods of the contained ImageList one must either
>> expose
>> the member itself or manually expose the various innate features of an
>> ImageList. This is done automatically if one is allowed to inherit
>> ImageList
>> in a 'public' way.
>>
>> Now that's just an exampe with ImageList, and ID is not a good
>> example, I
>> just used it to make my point. In general, it seems odd one would want
>> to
>> prevent any class from being inherited. I can see preventing the
>> overriding
>> or overloading of some class methods and keeping some members private.
>> But
>> complete denial? Why?
>>
>> [==P==]
>>
>>
>>


Dec 3 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.