tags:

views:

2257

answers:

9

Does C# have the notion of private / protected inheritance, and if not, why?

C++


class Foo : private Bar {
 public:
   ...
 }; 

C#


public abstract NServlet class : private System.Web.UI.Page
{
    // error "type expected"
}

I am implementing a "servlet like" concept in an .aspx page and I don't want the concrete class to have the ability to see the internals of the System.Web.UI.Page base.

+1  A: 

No, public inheritance only.

Chris Karcher
+1  A: 

You probably want a ServletContainer class that gets hooked up with a NServlet implementation. In my book, not allowing private / protected inheritance is not really a big deal and keeps the language less confusing - with LINQ etc. we allready have enough stuff to remember.

Daren Thomas
A: 

No it doesn't. What would the benefit be of allowing this type of restriction?

Scott Dorman
+1  A: 

You can hide inherited APIs from being publicly visible by declaring that same member in your class as private, and using the new keyword. See Hiding through Inheritance from MSDN.

bdukes
+3  A: 

If you want the NServlet class to not know anything about the Page, you should look into using the Adapter pattern. Write a page that will host an instance of the NServlet class. Depending on what exactly you're doing, you could then write a wide array of classes that only know about the base class NServlet without having to pollute your API with asp.net page members.

Joel Martinez
+3  A: 

C# allows public inheritance only. C++ allowed all three kinds. Public inheritance implied a "IS-A" type of relationship, and private inheritance implied a "Is-Implemented-In-Terms-Of" kind of relationship. Since layering (or composition) accomplished this in an arguably simpler fashion, private inheritance was only used when absolutely required by protected members or virtual functions required it - according to Scott Meyers in Effective C++, Item 42. My guess would be that the authors of C# did not feel this additional method of implementing one class in terms of another was necessary.

Brian Stewart
As you can simply use composition in this case, I'd say they were right.
peSHIr
+1  A: 

@bdukes: Keep in mind that you aren't truly hiding the member. E.g.:

class Base
{
   public void F() {}
}
class Derived: Base
{
   new private void F() {}
}

Base o = new Derived();
o.F();  // works

EDIT: But this accomplishes the same as private inheritance in C++, which is what the questioner wanted :)

Chris Karcher
A: 

c# support only public inheritance.....

+1  A: 

No it doesn't. What would the benefit be of allowing this type of restriction?

Private and protected inheritance is good for encapsulation (information hiding). Protected* inheritance is supported in C++, although it isn’t in Java. Here’s an example from my project where it would be useful.

There is a base class in as 3rd party framework**. It has dozens of settings plus properties and methods for manipulating them. The base class doesn’t make a lot of checking when individual settings are assigned, but it will generate an exception later if it encounters an unacceptable combination.

I’m making a child class with methods for assigning these settings (e.g. example, assigning carefully crafted settings from a file). It would be nice to deny the rest of the code (outside my child class) the ability to manipulate individual settings and mess them up.

That said, I think in C++ (which, again, supports private and protected inheritance) it's possible to cast the child class up to parent and get access to parent's public members. (See also Chris Karcher's comment in this thread.) Still, protected inheritance improves information hiding. If members of a class B1 need to be truly hidden within other classes C1 and C2, it can be arranged by making a protected variable of a class B1 within C1 and C2. Protected instance of B1 will be available to children of C1 and C2. Of course, this approach by itself doesn't provide polymorphism between C1 and C2. But polymorphism can be added (if desired) by inheriting C1 and C2 from a common interface I1.

* For brevity will use "protected" instead of "private and protected".

** National Instruments Measurement Studio in my case.

  • Nick
Nick Alexeev