Constructors and Inheritance - c#

Lets take an example in C#
public class Foo
{
public Foo() { }
public Foo(int j) { }
}
public class Bar : Foo
{
}
Now, All the public members of Foo is accessible in Bar except the constructor.
I cannot do something like
Bar bb = new Bar(1);
Why the constructors are not inheritable?
UPDATE
I do understand we can chain constructors, but I would like to know why the above construct is not valid. I am sure there should be a valid reason for it.

Constructors are not inheritable because it might cause weird and unintended behavior. More specifically, if you added a new constructor to a base class, all derived classes get an instance of that constructor. That's a bad thing in some cases, because maybe your base class specifies parameters that don't make sense for your derived classes.
A commonly given example for this is that in many languages, the base class for all objects (commonly called "Object") has a constructor with no parameters. If constructors were inherited, this would mean that all objects have a parameterless constructor, and there's no way to say "I want people who make an instance of this class to provide parameters X, Y and Z, otherwise their code shouldn't compile." For many classes, it's important that certain parameters be defined for their proper function, and making constructors non-heritable is part of the way that class authors can guarantee that some parameters are always defined.
Edit to respond to comments: Ramesh points out that if constructors were inherited as he would like them to be, he could always override base class constructors using privately declared constructors in each derived class. That is certainly true, but there it a logistical problem with this strategy. It requires that writers of derived classes have to watch base classes closely and add a private constructor if they want block inheritance of the base class constructor. Not only is this a lot of work for people writing derived classes, this kind of implicit dependency across classes is exactly the sort of thing that can cause weird behavior.
Ramesh - it's not that what you describe would be impossible to add to a language. In general it's not done because that sort of behavior could confuse people and lead to a lot of extra debugging and code writing.
Quintin Robinson provides some very worthwhile responses to this question in the comments that are definitely worth reading.

They are (via chaining), you would have to chain the constructor in your derived object.. IE:
public class Foo
{
public Foo() { }
public Foo(int j) { }
}
public class Bar : Foo
{
public Bar() : base() { }
public Bar(int j) : base(j) { }
}
The constructors in the derived objects will then chain the calls do the constructors in the base objects.
This article provides some more examples if you want further reading.

One reason why you might introduce a constructor into a class is because it makes no sense to have an instance of that class without a specific "dependency". For example, it might be a data-access class that has to have a connection to a database:
public class FooRepository
{
public FooRepository(IDbConnection connection) { ... }
}
If all the public constructors from base classes were available, then a user of your repository class would be able to use System.Object's default constructor to create an invalid instance of your class:
var badRepository = new FooRepository();
Hiding inherited constructors by default means that you can enforce dependencies without worrying about users creating "invalid" instances.

Suppose constructors were inheritable. How would you disable the inherited constructors in the many cases were they don't make sense for a subclass?
Rather than complicating the language with a mechanism to block inheritance, the language designers opted for simply making constructors not inheritable.

The Foo constructor can only know how to initialize a Foo object, so it makes no sense that it should also know how to initialize any potential subclass
public class Bar : Foo
{
public Bar(int i) : base(i) { }
}
The story the constructor tells is: "Hey base class please do whatever work you need to do to be in a good state so that I can go ahead and set up myself properly".

Constructors are not inheritable for design reasons. (Note that this is the same situation in every object-oriented language of which I know.) The simple answer is that in many cases you'd really not want the same constructors as the base class to be available. See this SO thread for some more complete explanations.

Some discussions
Joel's forum
Eric Gunnerson's blog
The basic idea is to provide as much control to the creator as possible. And you can have private bases. How'd you create the object then?

I think you can do the following:
public class Bar : Foo
{
public Bar (int i)
: base (i)
{
}
}
I may be a bit off -- but it's the general idea.

The simple answer is that the language doesn't work that way.
The real question you are asking for though is why it doesn't work that way :-) Well it is an arbitrary choice, and it follows on from C++ and Java (and very possibly many other langauges that influenced C#).
The likely reason is that the compiler will only generate a constructor that takes no arguments and simply calls the parent is that if you want more than what the compiler makes you do it yourself. This is the best choice since odds are you do more than suply calling the parent constructor.

Really, its because the parent constructor wouldn't fully initialize the child object. A constructor is kind of a personal thing in that respect. That's why most languages don't inherit constructors.

Related

Force a class to implement a specific constructor [duplicate]

Is there a way of forcing a (child) class to have constructors with particular signatures or particular static methods in C# or Java?
You can't obviously use interfaces for this, and I know that it will have a limited usage. One instance in which I do find it useful is when you want to enforce some design guideline, for example:
Exceptions
They should all have the four canonical constructors, but there is no way to enforce it. You have to rely on a tool like FxCop (C# case) to catch these.
Operators
There is no contract that specifies that two classes can be summed (with operator+ in C#)
Is there any design pattern to work around this limitation?
What construct could be added to the language to overcome this limitation in future versions of C# or Java?
Using generics you can force a type argument to have a parameterless constructor - but that's about the limit of it.
Other than in generics, it would be tricky to actually use these restrictions even if they existed, but it could sometimes be useful for type parameters/arguments. Allowing static members in interfaces (or possibly static interfaces) could likewise help with the "generic numeric operator" issue.
I wrote about this a little while ago when facing a similar problem.
Not enforced at compile-time, but I have spent a lot of time looking at similar issues; a generic-enabled maths library, and an efficient (non-default) ctor API are both avaiable in MiscUtil. However, these are only checked at first-usage at runtime. In reality this isn't a big problem - your unit tests should find any missing operator / ctor very quickly. But it works, and very quickly...
You could use the Factory pattern.
interface Fruit{}
interface FruitFactory<F extends Fruit>{
F newFruit(String color,double weight);
Cocktail mixFruits(F f1,F f2);
}
You could then create classes for any type of Fruit
class Apple implements Fruit{}
class AppleFactory implements FruitFactory<Apple>{
public Apple newFruit(String color, double weight){
// create an instance
}
public Cocktail mixFruits(Apple f1,Apple f2){
// implementation
}
}
This does not enforce that you can't create instance in another way than by using the Factory but at least you can specify which methods you would request from a Factory.
Force Constructors
You can't. The closest that you can come is make the default constructor private and then provide a constructor that has parameters. But it still has loopholes.
class Base
{
private Base() { }
public Base(int x) {}
}
class Derived : Base
{
//public Derived() { } won't compile because Base() is private
public Derived(int x) :base(x) {}
public Derived() : base (0) {} // still works because you are giving a value to base
}
The problem in the language is that static methods are really second class citizens (A constructor is also a kind of static method, because you don't need an instance to start with).
Static methods are just global methods with a namespace, they don't really "belong" to the class they are defined in (OK, they have access to private (static) methods in the class, but that's about it).
The problem on the compiler level is that without a class instance you don't have a virtual function table, which means you cannot use all the inheritance and polymorphism stuff.
I think one could make it work by adding a global/static virtual table for each class but if it hasn't been done yet, there's probably a good reason for it.
Here is I would solve it if I were a language designer.
Allow interfaces to include static methods, operators and constructors.
interface IFoo
{
IFoo(int gottaHaveThis);
static Bar();
}
interface ISummable
{
operator+(ISummable a, ISummable b);
}
Don't allow the corresponding new IFoo(someInt) or IFoo.Bar()
Allow constructors to be inherited (just like static methods).
class Foo: IFoo
{
Foo(int gottaHaveThis) {};
static Bar() {};
}
class SonOfFoo: Foo
{
// SonOfFoo(int gottaHaveThis): base(gottaHaveThis); is implicitly defined
}
class DaughterOfFoo: Foo
{
DaughhterOfFoo (int gottaHaveThis) {};
}
Allow the programmer to cast to interfaces and check, if necessary, at run time if the cast is semantically valid even if the class does not specify explicitly.
ISummable PassedFirstGrade = (ISummable) 10;
Unfortunately you can't in C#. Here is a punch at it though:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Foo.Instance.GetHelloWorld());
Console.ReadLine();
}
}
public class Foo : FooStaticContract<FooFactory>
{
public Foo() // Non-static ctor.
{
}
internal Foo(bool st) // Overloaded, parameter not used.
{
}
public override string GetHelloWorld()
{
return "Hello World";
}
}
public class FooFactory : IStaticContractFactory<Foo>
{
#region StaticContractFactory<Foo> Members
public Foo CreateInstance()
{
return new Foo(true); // Call static ctor.
}
#endregion
}
public interface IStaticContractFactory<T>
{
T CreateInstance();
}
public abstract class StaticContract<T, Factory>
where Factory : IStaticContractFactory<T>, new()
where T : class
{
private static Factory _factory = new Factory();
private static T _instance;
/// <summary>
/// Gets an instance of this class.
/// </summary>
public static T Instance
{
get
{
// Scary.
if (Interlocked.CompareExchange(ref _instance, null, null) == null)
{
T instance = _factory.CreateInstance();
Interlocked.CompareExchange(ref _instance, instance, null);
}
return _instance;
}
}
}
public abstract class FooStaticContract<Factory>
: StaticContract<Foo, Factory>
where Factory : IStaticContractFactory<Foo>, new()
{
public abstract string GetHelloWorld();
}
Well, I know from the wording of your question you are looking for compile-time enforcement. Unless someone else has a brilliant suggestion/hack that will allow you to do this the way you are implying the compiler should, I would suggest that you could write a custom MSbuild task that did this. An AOP framework like PostSharp might help you accomplish this at comiple-time by piggy backing on it's build task model.
But what is wrong with code analysis or run-time enforcement? Maybe it's just preference and I respect that, but I personally have no issues with having CA/FXCop check these things... and if you really want to force downstream implementers of your classes to have constructor signatures, you can always add rules run-time checking in the base class constructor using reflection.
Richard
I'm unsure as to what you are trying to achieve, can you please elaborate? The only reason for forcing a specific constructor or static method accross different classes is to try and execute them dynamically at run time, is this correct?
A constructor is intended to be specific to a particular class, as it is intended to initialise the specific needs of the class. As I understand it, the reason you would want to enforce something in a class hierarchy or interface, is that it is an activity/operation relevant to the process being performed, but may vary in different circumstances. I believe this is the intended benefit of polymorphism, which you can't achieve using static methods.
It would also require knowing the specific type of the class you wanted to call the static method for, which would break all of the polymorphic hiding of differences in behaviour that the interface or abstract class is trying to achieve.
If the behaviour being represented by the constructor is intended to be part of the contract between the client of these classes then I would add it explicitly to the interface.
If a hierarchy of classes have similar initialisation requirements then I would use an abstract base class, however it should be up to the inheriting classes how they find the parameter for that constructor, which may include exposing a similar or identical constructor.
If this is intended to allow you to create different instances at runtime, then I would recommend using a static method on an abstract base class which knows the different needs of all of the concrete classes (you could use dependency injection for this).

Abstract Method in Non Abstract Class

I want to know the reason behind the design of restricting Abstract Methods in Non Abstract Class (in C#).
I understand that the class instance won't have the definition and thus they wont be callable, but when static methods are defined,they are excluded from the instance too. Why abstract methods are not handled that way, any specific reason for the same?
They could be allowed in concrete class and the deriving class can be forced to implement methods, basically that is what, is done in case of abstract methods in an abstract class.
First, I think that what you're asking doesn't logically make sense. If you have an abstract method, it basically means that the method is unfinished (as #ChrisSinclair pointed out). But that also means the whole class is unfinished, so it also has to be abstract.
Or another way to put it: if you had an abstract method on a class that wasn't abstract, that would mean you had a method that cannot be called. But that means the method is not useful, you could remove it and it would all work the same.
Now, I'll try to be more concrete by using an example: imagine the following code:
Animal[] zoo = new Animal[] { new Monkey(), new Fish(), new Animal() };
foreach (Animal animal in zoo)
animal.MakeSound();
Here, Animal is the non-abstract base class (which is why I can put it directly into the array), Monkey and Fish are derived from Animal and MakeSound() is the abstract method. What should this code do? You didn't state that clearly, but I can imagine few options:
You can't call MakeSound() on a variable typed as Animal, you can call it only using a variable typed as one of the derived classes, so this is a compile error.
This is not a good solution, because the whole point of abstract is to be able to treat instances of derived classes as the base class, and still get behaviour that's specific to the derived class. If you want this, just put a normal (no abstract, virtual or override) method into each derived class and don't do anything with the base class.
You can't call MakeSound() on an object whose runtime type is actually Animal, so this is a runtime error (an exception).
This is also not a good solution. C# is a statically typed language and so it tries to catch errors like “you can't call this method” at compile time (with obvious exceptions like reflection and dynamic), so making this into a runtime error wouldn't fit with the rest of the language. Besides, you can do this easily by creating a virtual method in the base class that throws an exception.
To sum up, you want something that doesn't make much sense, and smells of bad design (a base class that behaves differently than its derived classes) and can be worked around quite easily. These are all signs of a feature that should not be implemented.
So, you want to allow
class C { abstract void M(); }
to compile. Suppose it did. What do you then want to happen when someone does
new C().M();
? You want an execution-time error? Well, in general C# prefers compile-time errors to execution-time errors. If you don't like that philosophy, there are other languages available...
I think you've answered your own question, an abstract method isn't defined initially. Therefore the class cannot be instanciated. You're saying it should ignore it, but by definition when adding an abstract method you're saying "every class created from this must implement this {abstract method}" hence the class where you define the abstract class must also be abstract because the abstract method is still undefined at that point.
The abstract class may contain abstract member. There is the only method declaration if any method has an abstract keyword we can't implement in the same class. So the abstract class is incompleted. That is why the object is not created for an abstract class.
Non-abstract class can't contain abstract member.
Example:
namespace InterviewPreparation
{
public abstract class baseclass
{
public abstract void method1(); //abstract method
public abstract void method2(); //abstract method
public void method3() { } //Non- abstract method----->It is necessary to implement here.
}
class childclass : baseclass
{
public override void method1() { }
public override void method2() { }
}
public class Program //Non Abstract Class
{
public static void Main()
{
baseclass b = new childclass(); //create instance
b.method1();
b.method2();
b.method3();
}
}
}
You can achieve what you want using "virtual" methods but using virtual methods can lead to more runtime business logic errors as a developer is not "forced" to implement the logic in the child class.
I think there's a valid point here. An abstract method is the perfect solution as it would "enforce" the requirement of defining the method body in children.
I have come across many many situations where the parent class had to (or it would be more efficient to) implement some logic but "Only" children could implement rest of the logic"
So if the opportunity was there I would happily mix abstract methods with complete methods.
#AakashM, I appreciate C# prefers compile time errors. So do I. And so does anybody. This is about thinking out-of-the-box.
And supporting this will not affect that.
Let's think out of the box here, rather than saying "hurrah" to big boy decisions.
C# compiler can detect and deny someone of using an abstract class directly because it uses the "abstract" keyword.
C# also knows to force any child class to implement any abstract methods. How? because of the use of the "abstract" keyword.
This is pretty simple to understand to anyone who has studied the internals of a programming language.
So, why can't C# detect an "abstract" keyword next to a method in a normal class and handle it at the COMPILE TIME.
The reason is it takes "reworking" and the effort is not worth supporting the small demand.
Specially in an industry that lacks people who think out of the boxes that big boys have given them.
It's still not clear why you would want that, but an alternative approach could be to force derived classes to provide a delegate instance. Something like this
class MyConcreteClass
{
readonly Func<int, DateTime, string> methodImpl;
// constructor requires a delegate instance
public MyConcreteClass(Func<int, DateTime, string> methodImpl)
{
if (methodImpl == null)
throw new ArgumentNullException();
this.methodImpl = methodImpl;
}
...
}
(The signature string MethodImpl(int, DateTime) is just an example, of course.)
Otherwise, I can recommend the other answers to explain why your wish probably isn't something which would make the world better.
So the answers above are correct: having abstract methods makes the class inherently abstract. If you cannot instance part of a class, then you cannot instance the class itself. However, the answers above didn't really discuss your options here.
First, this is mainly an issue for public static methods. If the methods aren't intended to be public, then you could have protected non-abstract methods, which are allowed in an abstract class declaration. So, you could just move these static methods to a separate static class without much issue.
As an alternative, you could keep those methods in the class, but then instead of having abstract methods, declare an interface. Essentially, you have a multiple-inheritance problem as you want the derived class to inherit from two conceptually different objects: a non-abstract parent with public static members, and an abstract parent with abstract methods. Unlike some other frameworks, C# does permit multiple inheritance. Instead, C# offers a formal interface declaration that is intended to fill this purpose. Moreover, the whole point of abstract methods, really, is just to impose a certain conceptual interface.
I have a scenario very similar to what the OP is trying to achieve. In my case the method that I want to make abstract would be a protected method and would only be known to the base class. So the "new C().M();" does not apply because the method in question is not public. I want to be able to instantiate and call public methods on the base class (therefore it needs to be non-abstract), but I need these public methods to call a protected implementation of the protected method in the child class and have no default implementation in the parent. In a manner of speaking, I need to force descendants to override the method. I don't know what the child class is at compile time due to dependency injection.
My solution was to follow the rules and use a concrete base class and a virtual protected method. For the default implementation, though, I throw a NotImplementedException with the error "The implementation for method name must be provided in the implementation of the child class."
protected virtual void MyProtectedMethod()
{
throw new NotImplementedException("The implementation for MyProtectedMethod must be provided in the implementation of the child class.");
}
In this way a default implementation can never be used and implementers of descendant implementations will quickly see that they missed an important step.

implementing polymorphism in c#, how best to do it?

first question here, so hopefully you'll all go gently on me!
I've been reading an awful lot over the past few days about polymorphism, and trying to apply it to what I do in c#, and it seems there are a few different ways to implement it. I hope I've gotten a handle on this, but I'd be delighted even if I haven't for clarification.
From what I can see, I've got 3 options:
I can just inherit from a base
class and use the keyword
'virtual' on any methods that I
want my derived classes to
override.
I could implement an abstract class with virtual methods
and do it that way,
I could use an interface?
From what I can see, if I don't require any implementation logic in the base, then an interface gives me the most flexibility (as I'm then not limiting myself with regards multiple inheritance etc.), but if I require the base to be able to do something on top of whatever the derived classes are doing, then going with either 1 or 2 would be the better solution?
Thanks for any input on this guys - I have read so much this weekend, both on this site and elsewhere, and I think I understand the approaches now, yet I just want to clarify in a language specific way if I'm on the right track. Hopefully also I've tagged this correctly.
Cheers,
Terry
An interface offers the most abstraction; you aren't tied to any specific implementation (useful if the implementation must, for other reasons, have a different base class).
For true polymorphism, virtual is a must; polymorphism is most commonly associated with type subclassing...
You can of course mix the two:
public interface IFoo {
void Bar();
}
class Foo : IFoo {
public virtual void Bar() {...}
}
class Foo2 : Foo {
public override ...
}
abstract is a separate matter; the choice of abstract is really: can it be sensibly defined by the base-class? If there is there no default implementation, it must be abstract.
A common base-class can be useful when there is a lot of implementation details that are common, and it would be pointless to duplicate purely by interface; but interestingly - if the implementation will never vary per implementation, extension methods provide a useful way of exposing this on an interface (so that each implementation doesn't have to do it):
public interface IFoo {
void Bar();
}
public static class FooExtensions {
// just a silly example...
public static bool TryBar(this IFoo foo) {
try {
foo.Bar();
return true;
} catch {
return false;
}
}
}
All three of the above are valid, and useful in their own right.
There is no technique which is "best". Only programming practice and experience will help you to choose the right technique at the right time.
So, pick a method that seems appropriate now, and implement away.
Watch what works, what fails, learn your lessons, and try again.
Interfaces are usually favored, for several reasons :
Polymorphisme is about contracts, inheritance is about reuse
Inheritance chains are difficult to get right (especially with single inheritance, see for instance the design bugs in the Windows Forms controls where features like scrollability, rich text, etc. are hardcoded in the inheritance chain
Inheritance causes maintenance problems
That said, if you want to leverage common functionnality, you can use interfaces for polymorphism (have your methods accept interfaces) but use abstract base classes to share some behavior.
public interface IFoo
{
void Bar();
enter code here
}
will be your interface
public abstract class BaseFoo : IFoo
{
void Bar
{
// Default implementation
}
}
will be your default implementation
public class SomeFoo : BaseFoo
{
}
is a class where you reuse your implementation.
Still, you'll be using interfaces to have polymorphism:
public class Bar
{
int DoSometingWithFoo(IFoo foo)
{
foo.Bar();
}
}
notice that we're using the interface in the method.
The first thing you should ask is "why do I need to use polymorphism?", because polymorphism is not and end by itself, but a mean to reach an end. Once you have your problem well defined, it should be more clear which approach to use.
Anyway, those three aproaches you commented are not exclusive, you still can mix them if you need to reuse logic between just some classes but not others, or need some distinct interfaces...
use abstract classes to enforce a class structure
use interfaces for describing behaviors
It really depends on how you want to structure your code and what you want to do with it.
Having a base class of type Interface is good from the point of view of testing as you can use mock objects to replace it.
Abstract classes are really if you wish to implement code in some functions and not others, as if an abstract class has nothing other than abstract functions it is effectively an Interface.
Remember that an abstract class cannot be instantiated and so for working code you must have a class derived from it.
In practice all are valid.
I tend to use an abstract class if I have a lot of classes which derive from it but on a shallow level (say only 1 class down).
If I am expecting a deep level of inheritence then I use a class with virtual functions.
Eitherway it's best to keep classes simple, along with their inheritence as the more complex they become the more likelyhood of introducing bugs.

How to handle a class you want to extend which is sealed in the .NET library?

I was reading somewhere about how to handle the issue of wanting to extend a sealed class in the .NET Framework library.
This is often a common and useful task to do, so it got me thinking, in this case, what solutions are there? I believe there was a "method" demonstrated to extend a sealed class in the article I read, but I cannot remember now (it wasn't extension methods).
Is there any other way?
Thanks
There is 'fake' inheritance. That is, you implement the base class and any interfaces the other class implements:
// Given
sealed class SealedClass : BaseClass, IDoSomething { }
// Create
class MyNewClass : BaseClass, IDoSomething { }
You then have a private member, I usually call it _backing, thus:
class MyNewClass : BaseClass, IDoSomething
{
SealedClass _backing = new SealedClass();
}
This obviously won't work for methods with signatures such as:
void NoRefactoringPlease(SealedClass parameter) { }
If the class you want to extend inherits from ContextBoundObject at some point, take a look at this article. The first half is COM, the second .Net. It explains how you can proxy methods.
Other than that, I can't think of anything.
Extension methods is one way, the alternative being the Adapter Pattern. Whereby you write a class that delegates some calls to the sealed one you want to extend, and adds others. It also means that you can adapt the interface completely into something that your app would find more appropriate.
this method may have already been mentioned above by it's formal name, but i don't know it's formal name, so here it is. This example "extends" the TextBox class (example in VB). I believe an advantage of this method is that you do not need to explicitly code or expose built-in members. Hope this is relevant:
VB Class Module "MyTextBox":
public Base as TextBox, CustomProperty as Integer
Private Sub Init(newTextBox as TextBox)
Set Base = newTextBox
End Sub
public Property Get CustomProperty2() As String
CustomProperty2 = "Something special"
End Property
To call the code, you might say:
Dim MyBox as New MyTextBox
MyBox.Init MyForm.TextBox3
from here you have access to all built-in members, plus your custom members.
Debug.Print MyBox.Base.Text
MyBox.CustomProperty = 44
For extra polish, you can make Base the default property of the class, and then you can leave out "Base" when you call properties of the Base class. You call Base members like this:
Debug.Print MyBox().Text
MyBox().Text = "Hello World"
VBA Demo
Maybe use the Decorator pattern?
Other than extension methods, this is the only sensible technique I can think of.
No, you can't extend a sealed class in any legitimate way.
TypeMock allows you to mock sealed classes, but I doubt that they'd encourage you to use the same technique for production code.
If a type has been sealed, that means the class designer has not designed it for inheritance. Using it for inheritance at that point may well cause you lots of pain, either now or when the implementation is changed at a later date.
Prefer composition to inheritance - it's a lot more robust, in my experience. See item 16 in "Effective Java (2nd edition)" for more on this.
The only way I know to "extend" a sealed class without extension methods is by wrapping it. For example:
class SuperString
{
private String _innerString;
public SuperString(String innerString)
{
_innerString = innerString;
}
public int ToInt()
{
return int.Parse(_innerString);
}
}
You'd need to expose all of the same methods/properties as the string class.
Some frameworks allow you to extend existing objects. In WPF, see Dependency Properties. For Windows Forms, see IExtenderProvider.
How about extension methods? You can "add" additional methods that way, without having to deal with the inheritance restriction.

C# - Can publicly inherited methods be hidden (e.g. made private to derived class)

Suppose I have BaseClass with public methods A and B, and I create DerivedClass through inheritance.
e.g.
public DerivedClass : BaseClass {}
Now I want to develop a method C in DerivedClass that uses A and B. Is there a way I can override methods A and B to be private in DerivedClass so that only method C is exposed to someone who wants to use my DerivedClass?
It's not possible, why?
In C#, it is forced upon you that if you inherit public methods, you must make them public. Otherwise they expect you not to derive from the class in the first place.
Instead of using the is-a relationship, you would have to use the has-a relationship.
The language designers don't allow this on purpose so that you use inheritance more properly.
For example one might accidentally confuse a class Car to derive from a class Engine to get it's functionality. But an Engine is functionality that is used by the car. So you would want to use the has-a relationship. The user of the Car does not want to have access to the interface of the Engine. And the Car itself should not confuse the Engine's methods with it's own. Nor Car's future derivations.
So they don't allow it to protect you from bad inheritance hierarchies.
What should you do instead?
Instead you should implement interfaces. This leaves you free to have functionality using the has-a relationship.
Other languages:
In C++ you simply specify a modifier before the base class of private, public or protected. This makes all members of the base that were public to that specified access level. It seems silly to me that you can't do the same in C#.
The restructured code:
interface I
{
void C();
}
class BaseClass
{
public void A() { MessageBox.Show("A"); }
public void B() { MessageBox.Show("B"); }
}
class Derived : I
{
public void C()
{
b.A();
b.B();
}
private BaseClass b;
}
I understand the names of the above classes are a little moot :)
Other suggestions:
Others have suggested to make A() and B() public and throw exceptions. But this doesn't make a friendly class for people to use and it doesn't really make sense.
When you, for instance, try to inherit from a List<object>, and you want to hide the direct Add(object _ob) member:
// the only way to hide
[Obsolete("This is not supported in this class.", true)]
public new void Add(object _ob)
{
throw NotImplementedException("Don't use!!");
}
It's not really the most preferable solution, but it does the job. Intellisense still accepts, but at compile time you get an error:
error CS0619: 'TestConsole.TestClass.Add(TestConsole.TestObject)' is obsolete: 'This is not supported in this class.'
That sounds like a bad idea. Liskov would not be impressed.
If you don't want consumers of DerivedClass to be able to access methods DeriveClass.A() and DerivedClass.B() I would suggest that DerivedClass should implement some public interface IWhateverMethodCIsAbout and the consumers of DerivedClass should actually be talking to IWhateverMethodCIsAbout and know nothing about the implementation of BaseClass or DerivedClass at all.
What you need is composition not inheritance.
class Plane
{
public Fly() { .. }
public string GetPilot() {...}
}
Now if you need a special kind of Plane, such as one that has PairOfWings = 2 but otherwise does everything a plane can.. You inherit plane. By this you declare that your derivation meets the contract of the base class and can be substituted without blinking wherever a base class is expected. e.g. LogFlight(Plane) would continue to work with a BiPlane instance.
However if you just need the Fly behavior for a new Bird you want to create and are not willing to support the complete base class contract, you compose instead. In this case, refactor the behavior of methods to reuse into a new type Flight. Now create and hold references to this class in both Plane and Bird.
You don't inherit because the Bird does not support the complete base class contract... ( e.g. it cannot provide GetPilot() ).
For the same reason, you cannot reduce the visibility of base class methods when you override.. you can override and make a base private method public in the derivation but not vice versa. e.g. In this example, if I derive a type of Plane "BadPlane" and then override and "Hide" GetPilot() - make it private; a client method LogFlight(Plane p) will work for most Planes but will blow up for "BadPlane" if the implementation of LogFlight happens to need/call GetPilot(). Since all derivations of a base class are expected to be 'substitutable' wherever a base class param is expected, this has to be disallowed.
#Brian R. Bondy pointed me to an interesting article on Hiding through inheritance and the new keyword.
http://msdn.microsoft.com/en-us/library/aa691135(VS.71).aspx
So as workaround I would suggest:
class BaseClass
{
public void A()
{
Console.WriteLine("BaseClass.A");
}
public void B()
{
Console.WriteLine("BaseClass.B");
}
}
class DerivedClass : BaseClass
{
new public void A()
{
throw new NotSupportedException();
}
new public void B()
{
throw new NotSupportedException();
}
public void C()
{
base.A();
base.B();
}
}
This way code like this will throw a NotSupportedException:
DerivedClass d = new DerivedClass();
d.A();
The only way to do this that I know of is to use a Has-A relationship and only implement the functions you want to expose.
Hiding is a pretty slippery slope. The main issues, IMO, are:
It's dependent upon the design-time
declaration type of the instance,
meaning if you do something like
BaseClass obj = new SubClass(), then
call obj.A(), hiding is defeated. BaseClass.A() will be executed.
Hiding can very easily obscure
behavior (or behavior changes) in
the base type. This is obviously
less of a concern when you own both
sides of the equation, or if calling 'base.xxx' is part of your sub-member.
If you actually do own both sides of the base/sub-class equation, then you should be able to devise a more manageable solution than institutionalized hiding/shadowing.
I would say that if you have a codebase that you are wanting to do this with, it is not the best designed code base. It's typically a sign of a class in one level of the heirarchy needing a certain public signature while another class derived from that class doesn't need it.
An upcoming coding paradigm is called "Composition over Inheritance." This plays directly off of the principles of object-oriented development (especially the Single Responsibility Principle and Open/Closed Principle).
Unfortunately, the way a lot of us developers were taught object-orientation, we have formed a habit of immediately thinking about inheritance instead of composition. We tend to have larger classes that have many different responsibilities simply because they might be contained with the same "Real World" object. This can lead to class hierarchies that are 5+ levels deep.
An unfortunate side-effect that developers don't normally think about when dealing with inheritance is that inheritance forms one of the strongest forms of dependencies that you can ever introduce into your code. Your derived class is now strongly dependant on the class it was inherited from. This can make your code more brittle in the long run and lead to confounding problems where changing a certain behavior in a base class breaks derived classes in obscure ways.
One way to break your code up is through interfaces like mentioned in another answer. This is a smart thing to do anyways as you want a class's external dependencies to bind to abstractions, not concrete/derived types. This allows you to change the implementation without changing the interface, all without effecting a line of code in your dependent class.
I would much rather than maintain a system with hundreds/thousands/even more classes that are all small and loosely-coupled, than deal with a system that makes heavy use of polymorphism/inheritance and has fewer classes that are more tightly coupled.
Perhaps the best resource out there on object-oriented development is Robert C. Martin's book, Agile Software Development, Principles, Patterns, and Practices.
If they're defined public in the original class, you cannot override them to be private in your derived class. However, you could make the public method throw an exception and implement your own private function.
Edit: Jorge Ferreira is correct.
While the answer to the question is "no", there is one tip I wish to point out for others arriving here (given that the OP was sort of alluding to assembly access by 3rd parties). When others reference an assembly, Visual Studio should be honoring the following attribute so it will not show in intellisense (hidden, but can STILL be called, so beware):
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
If you had no other choice, you should be able to use new on a method that hides a base type method, return => throw new NotSupportedException();, and combine it with the attribute above.
Another trick depends on NOT inheriting from a base class if possible, where the base has a corresponding interface (such as IList<T> for List<T>). Implementing interfaces "explicitly" will also hide those methods from intellisense on the class type. For example:
public class GoodForNothing: IDisposable
{
void IDisposable.Dispose() { ... }
}
In the case of var obj = new GoodForNothing(), the Dispose() method will not be available on obj. However, it WILL be available to anyone who explicitly type-casts obj to IDisposable.
In addition, you could also wrap a base type instead of inheriting from it, then hide some methods:
public class MyList<T> : IList<T>
{
List<T> _Items = new List<T>();
public T this[int index] => _Items[index];
public int Count => _Items.Count;
public void Add(T item) => _Items.Add(item);
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
void ICollection<T>.Clear() => throw new InvalidOperationException("No you may not!"); // (hidden)
/*...etc...*/
}

Categories