Inheritance question

  • Thread starter Thread starter Michael A. Covington
  • Start date Start date
M

Michael A. Covington

Suppose class X has some public properties, and class Y inherits from X. Is
there a way that some of the public properties of X can be private (hidden)
in Y (but still usable by the methods inherited from X that use them)?
 
As far as I know, there's no way of "hiding" inherited properies by changing
their visibility. To benefit most from polymorphism, it should always be
possible for clients to use a derived subclass as if it were a base class
without knowing it. Changing visibility in this way would break that -
suddenly your subclass does not *really* expose the interface of your base
class anymore. The Liskov Substitution Principle explains why here:
http://www.objectmentor.com/resources/articles/lsp.pdf

One option you do have is to make the properties of the base class
protected, and then re-publish only the ones you need as public in the
subclass under a different name. For example:

class myBase{
protected string name{ get{ return _name;}}
}
class mySubclass : myBase{
public string Name{ get{ return base.name; }}
}

What's your scenario? I've wished for this ability too, in the case where I
use a code generator to create a base class that I then want to extend in a
user-edited subclass. I've often realised it would be more convenient to
hide a few methods than to have to re-publish most of them as public. In my
case, the *real* problem here is that I really only need *one* class, but
instead I'm using 2 classes and inheritance to keep the generated code
separate from the hand-modified.

Hope this helps

Tobin
 
Hi Michael,

if class Y inherits from X, than every instance of class Y is a speialized
instance of class X.
Evrything that can be done with class X can be done with class Y.
So what is public in X also is public in Y.

Code in class X can use any member of class X even if it's private. That
also is valid, if the expression is of type
Y.
 
Hi
class x
{
public stuff(){}
public stuff1(){}
}
class y:x
{
private override stuff()
{
base.stuff();
}
private override stuff1()
{
base.stuff();
}
}

The above may help
Thanks-
Karthik . S . Rao
 
Sorry, some corrections:

class x
{
public void stuff(){}
public void stuff1(){}
}
class y:x
{
private override void stuff()
{
base.stuff();
}
private override void stuff1()
{
base.stuff1();
}
}
Hope it may help you
Thanks-
Karthik. S. Rao
 
1. You can't override a none virtual method.
2. If you did have a virtual method in the base, virtual or abstract members
cannot be private.
3. If you used method Shadowing (hiding) by using the new keyword,
unfortunately the inherited class x public members would still be visible.

Br,

Mark.
 
Mark-
1) Sorry i forgot about the virtual keyword
2) you are right.
3) you are right

????!!!!!!
Thnaks-
Karthik. S. Rao
 
Don't worry, when I first saw this post I probably thought the same as you
i.e. 'yeah of cause you can do this', but fortunately I tried it. :)
 
Tobin Harris said:
As far as I know, there's no way of "hiding" inherited properies by
changing their visibility. To benefit most from polymorphism, it should
always be possible for clients to use a derived subclass as if it were a
base class without knowing it. ...
Thanks.

What's your scenario? I've wished for this ability too, in the case where
I use a code generator to create a base class that I then want to extend
in a user-edited subclass.

I'm writing an extension of TreeView in which a few properties of TreeView
that are normally changeable by the user (programmer) should not be changed.
That's why I wanted to hide them.
 
Hi Michael,

now i see your problem.
There are to option.
1.) You don't inherit from treeview, but build a Control that contains a
treeview.
Then you implement all members you need to be public simply by calling the
TreeView memberes.
This would be much work, if almost all members have to be implemented
(depends on your final goal.)
Also it would break inheritance (your control wouldn't be a TreeView.
Third additional memberes in newer versions of TreeView would'nt be
implemented your control. (but that also can be an advatage; maybe they
shouldn't be implemented ;) )

2.)
You override the setter of that properties simply by ignoring the value.
Would only be possible, if that properties are virtual.
Then your Control is a (specialized) TreeView and the value of that
propertie remains fixed.
But that could lead to unexpected behavior, if a client of your control
tries to change that propertie.
This techinc sounds very crude, but it's even used by the Framework. (e.g.
TextBox.Height if the TextBox is SingleLine).

Hope that helps
Christof
 
One suggestion I've seen in the past to get around this problem is to create
a new method or property in your inheriting class and to raise an exception
telling the programmer that "This property is not intended for public use
etc etc." You could also add an attribute to the said items to prevent the
editor from displaying them.

Br,

Mark.
 
Mark Broadbent said:
One suggestion I've seen in the past to get around this problem is to
create a new method or property in your inheriting class and to raise an
exception telling the programmer that "This property is not intended for
public use etc etc." You could also add an attribute to the said items to
prevent the editor from displaying them.

That last thing would be sufficient. How do I do that?
 
Do Not Restrict The Behavior of the Subclass
http://www.parashift.com/c++-faq-lite/proper-inheritance.html

[21.1] Should I hide member functions that were public in my base class?
Never, never, never do this. Never. Never!

Attempting to hide (eliminate, revoke, privatize) inherited public
member functions is an all-too-common design error. It usually stems
from muddy thinking.

Resist the temptation to extend a class by overriding a public method in
the base class and just throwing a MethodNotSupported exception in the
body of the method in the subclass. Throwing an exception instead of
providing an implementation unilaterally revokes the contract between
the caller and the base class. Just as importantly, this contractual
failure may not be realized until runtime.

Regards,
Jeff
 
Christof Nordiek said:
But that could lead to unexpected behavior, if a client of your control
tries to change that propertie.
This techinc sounds very crude, but it's even used by the Framework. (e.g.
TextBox.Height if the TextBox is SingleLine).

In most cases it would be preferrable to throw an exception. That way
programmers of the treeview will be alerted when they use features that are
not supported. I wouldn't see this as crude at all.

Michael
 
Michael A. Covington said:
That last thing would be sufficient. How do I do that?

[Browsable(false)] i think. Note that browsable might be mispelt or I might
be wrong entirely.
 
Yes, certainly there is an argument to be said for this however you are then
moving into the area of distinction between what is a subclass and what is a
subtype.
Now from an entire OOP design point of view I'd say that if you are needing
to hide public methods like this in your subclass then potentially you've
possibly implemented too much functionality in your base class. But there
are certain base classes that we want to use which are not under our control
and yet still provide all (and more that we don't) of the behaviour that
needs to be inherited as is the case here.
Best OOP example. What would you do with a Platypus class that inherits a
Mammal class?
Mammal m = new Mammal();
Mammal n = m.GivesBirth();

Platypus p = new Platypus();
Platypus q = p.GivesBirth(); //whoops! thats not valid for a Platypus
Platypus.Egg r = p.LaysEgg();
Platypus s = r.Hatch();
//cute aint he!

Another way around this (to stick to your rule) is to encapsulate the
functionality of the Mammal class via a private object within the Platypus
class and only expose and implement those methods and properties that are
valid.

Finally I would like to add that your quote does come from a c++ faq, and c#
and c++ are a bit like comparing apples and oranges, but is not without
merit. Your point should be taken into account.

Br,

Mark.
 
Hi Michael, I've only ever done this once and believe I used the following
http://msdn.microsoft.com/library/d...ntmodeleditorbrowsableattributeclasstopic.asp

However you might like to review (I think at bottom -Bob Powel's post) this
article. It suggests another method.

Let me know how you get on.

Br,

Mark.


Michael C said:
Michael A. Covington said:
That last thing would be sufficient. How do I do that?

[Browsable(false)] i think. Note that browsable might be mispelt or I
might be wrong entirely.
 
Thanks!

Mark Broadbent said:
Hi Michael, I've only ever done this once and believe I used the following
http://msdn.microsoft.com/library/d...ntmodeleditorbrowsableattributeclasstopic.asp

However you might like to review (I think at bottom -Bob Powel's post)
this article. It suggests another method.

Let me know how you get on.

Br,

Mark.


Michael C said:
Michael A. Covington said:
That last thing would be sufficient. How do I do that?

[Browsable(false)] i think. Note that browsable might be mispelt or I
might be wrong entirely.
 
[21.1] Should I hide member functions that were public in my base class?
Never, never, never do this. Never. Never!

This is too strong. What do you do when you have no control over the
base class? What do you do when a library (the .NET Framework, for
example) provides a base class that gives you all of the functionality
you need, but has some methods and properties that don't apply to the
implementation you want to provide? Do you:

1. Tell Microsoft that they designed their base class badly, and wait
for them to fix it.

or

2. Tell your boss that you have to build a complete new implementation
of, say, XmlReader because it has five methods that don't apply to the
class you want to build (but otherwise it's a perfect fit),

or

3. Hold you nose, override the methods in question, and throw a
MethodNotSupported exception if they're called in your subclass, or, if
they're not virtual, declare "new" versions of them and do likewise?

If I were to do 1 or 2, I'd be fired.

Now, if I built the base class myself, then you're right: if I'm doing
this sort of nastiness in a subclass then my class hierarchy is wrong
and I really should fix it. In Mark's example below, GiveBirth() really
should be in an interface, called ILiveBirth or something, that all
Mammal classes except Platypus implement. However, as I said, this
assumes that I wrote Mammal and Platypus, and have the luxury (and the
time) to rebuild Mammal appropriately. If Mammal was supplied to me by
an outside party, or I published it to the world and so now can't
change it, then I have little choice but to hold my nose and hack the
subclass.

However, I do agree with Jeff in principle: if you're tempted to do
this then you'd better be ready to defend that decision at code review
time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top