Why "New" Keyword in C# [duplicate] - c#

I was looking at this blog post and had following questions:
Why do we need the new keyword, is it just to specify that a base class method is being hidden. I mean, why do we need it? If we don't use the override keyword, aren't we hiding the base class method?
Why is the default in C# to hide and not override? Why have the designers implemented it this way?

Good questions. Let me re-state them.
Why is it legal to hide a method with another method at all?
Let me answer that question with an example. You have an interface from CLR v1:
interface IEnumerable
{
IEnumerator GetEnumerator();
}
Super. Now in CLR v2 you have generics and you think "man, if only we'd had generics in v1 I would have made this a generic interface. But I didn't. I should make something compatible with it now that is generic so that I get the benefits of generics without losing backwards compatibility with code that expects IEnumerable."
interface IEnumerable<T> : IEnumerable
{
IEnumerator<T> .... uh oh
What are you going to call the GetEnumerator method of IEnumerable<T>? Remember, you want it to hide GetEnumerator on the non-generic base interface. You never want that thing to be called unless you're explicitly in a backwards-compat situation.
That alone justifies method hiding. For more thoughts on justifications of method hiding see my article on the subject.
Why does hiding without "new" cause a warning?
Because we want to bring it to your attention that you are hiding something and might be doing it accidentally. Remember, you might be hiding something accidentally because of an edit to the base class done by someone else, rather than by you editing your derived class.
Why is hiding without "new" a warning rather than an error?
Same reason. You might be hiding something accidentally because you've just picked up a new version of a base class. This happens all the time. FooCorp makes a base class B. BarCorp makes a derived class D with a method Bar, because their customers like that method. FooCorp sees that and says hey, that's a good idea, we can put that functionality on the base class. They do so and ship a new version of Foo.DLL, and when BarCorp picks up the new version, it would be nice if they were told that their method now hides the base class method.
We want that situation to be a warning and not an error because making it an error means that this is another form of the brittle base class problem. C# has been carefully designed so that when someone makes a change to a base class, the effects on code that uses a derived class are minimized.
Why is hiding and not overriding the default?
Because virtual override is dangerous. Virtual override allows derived classes to change the behaviour of code that was compiled to use base classes. Doing something dangerous like making an override should be something you do consciously and deliberately, not by accident.

If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class
However if you don't specify either new or overrides, the resulting output is the same as if you specified new, but you will get a compiler warning (as you may not be aware that you are hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
So it helps you to avoid mistakes and explicitly show what you want to do and it makes more readable code, so one can easily understand your code.

It is worth noting that the only effect of new in this context is to suppress a Warning. There is no change in semantics.
So one answer is: We need new to signal to the compiler that the hiding is intentional and to get rid of the warning.
The follow up question is: If you won't / can't override a method, why would you introduce another method with the same name? Because hiding is in essence a name-conflict. And you would of course avoid it in most cases.
The only good reason I can think of for intentional hiding is when a name is forced upon you by an interface.

In C# members are sealed by default meaning that you cannot override them (unless marked with the virtual or abstract keywords) and this for performance reasons. The new modifier is used to explicitly hide an inherited member.

If overriding was default without specifying the override keyword, you could accidentally override some method of your base just due to the name equality.
.Net compiler strategy is to emit warnings if something could go wrong, just to be safe, so in this case if overriding was default, there would have to be a warning for each overriden method - something like 'warning: check if you really want to override'.

My guess would mainly be due to the multiple interface inheritance. Using discreet interfaces it would be very possible that two distinct interfaces use the same method signature. Allowing the use of the new keyword would allow you to create these different implementations with one class, instead of having to create two distinct classes.
Updated ... Eric gave me an idea on how to improve this example.
public interface IAction1
{
int DoWork();
}
public interface IAction2
{
string DoWork();
}
public class MyBase : IAction1
{
public int DoWork() { return 0; }
}
public class MyClass : MyBase, IAction2
{
public new string DoWork() { return "Hi"; }
}
class Program
{
static void Main(string[] args)
{
var myClass = new MyClass();
var ret0 = myClass.DoWork(); //Hi
var ret1 = ((IAction1)myClass).DoWork(); //0
var ret2 = ((IAction2)myClass).DoWork(); //Hi
var ret3 = ((MyBase)myClass).DoWork(); //0
var ret4 = ((MyClass)myClass).DoWork(); //Hi
}
}

As noted, method/property hiding makes it possible to change things about a method or property which could not be readily changed otherwise. One situation where this can be useful is allowing an inherited class to have read-write properties which are read-only in the base class. For example, suppose a base class has a bunch of read-only properties called Value1-Value40 (of course, a real class would use better names). A sealed descendant of this class has a constructor that takes an object of the base class and copies the values from there; the class does not allow them to be changed after that. A different, inheritable, descendant declare a read-write properties called Value1-Value40 which, when read, behaves the same as the base class versions but, when written, allows the values to be written. The net effect will be that code which wants an instance of the base class that it knows will never change can create a new object of the read-only class, which can copy data from a passed-in object without having to worry whether that object is read-only or read-write.
One annoyance with this approach--perhaps someone can help me out--is that I don't know of a way to both shadow and override a particular property within the same class. Do any of the CLR languages allow that (I use vb 2005)? It would be useful if the base class object and its properties could be abstract, but that would require an intermediate class to override the Value1 to Value40 properties before a descendant class could shadow them.

Related

confusion regarding overriding rules C#

I have a litte confusion regarding method overriding and the validity of OOP priciples.
I know everything regarding sealing, shadowing, overriding, virtual etc. but I came across a scenario, that just confused me. Suppose I have:
class classA
{
public virtual void sayhello()
{
Console.WriteLine("hello I'm A");
}
};
class classB :classA
{
public override void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
class Program
{
static void Main(string[] args)
{
classB a = new classB();
a.sayhello();
}
}
According to everything I studied so far, a method declared as virtual or abstract (in abstract class) can be overriden using override keyword in child class. according to this, above code works perfect.
When I remove the virtual keyword, and then try to override the method using override keyword, then compiler gives error as:
cannot override inherited member 'inheritence.classA.sayhello()' because it is not marked virtual, abstract, or override
and then i removed the override key word, from child class, and provided the implementation as:
class classB :classA
{
public void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
In this case, the method could be overrided. I'm able to override the method, which is not virtual or abstract. so, my question is:
1. Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.
2. Why am I allowed to override the method this way? which is not even marked virtual?
3. Removing virtual keyword from classA method, it gave me the feeling of sealed method in classA, when I tried to override that method in classB. (as I mentioned the compiler error earlier). If i remove virtual, so that the child class may not override it, then WHY could the child class cleverly override it, removing its override keyword? Is this ONLY the case, sealed keyword is designed for?
I will like to tell you that you gave hidden the parent child method not overridden.
One more thing you might have not noted doing the same is seeing WARNING because in warning section it will be clearly mentioned that,
Warning 'line number' 'classB .sayhello' hides inherited member 'classA.sayhello'. Use the new
keyword if hiding was intended.
Your question,
Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.
No surely it did not violate the OOP principle as you have hide the base class method.
Why am I allowed to override the method this way? which is not even marked virtual?
Because C# not only supports overriding but also method hiding and A hiding method has to be declared using the new keyword. For More Information read dotnet_polymorphism and overriding-vs-method-hiding
Is this ONLY the case, sealed keyword is designed for?
From MSDN sealed sealed keyword is designed to prevent derivation of class and to negate the virtual aspect of the virtual members.
When applied to a class, the sealed modifier prevents other classes from inheriting from it.
sealed modifier can be only applied to a method or property that overrides a virtual method or property in a base class. This prevent further overriding specific virtual methods or properties but it can never stop method-hiding. Read Non-overridable method for more information
Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.
You did not override the parent method you have hidden the parent method.
so you can never access the parent method from the child class object as it was hidden by your child class method sayhello().
2.Why am I allowed to override the method this way? which is not even marked virtual?
because you can hide the parent methods with child implemetation.
I think this comes from C++ implementation, which used slicing (What is object slicing?).
While C# resembles mostly Java, in some cases (this one and the existence of value types) it follows the C++ way.
The reasoning after this is that, since your code calls method sayhello from an A variable, the programmer expects the logic of A.sayhello to be executed. It does not break OOP principles, since you are executing an A.sayhello implementation (so it must match the A.sayhello contract).
The difference with Java is not OOP vs not OOP, but that Java uses late binding (the actual method to be executed is decided at runtime based in a actual instance) while C# uses early binding (the method is decided at compile time) unless the method is virtual.
Personally I prefer late binding, while C# approach is correct from an OOP point of view, I find that usually the more specialized method should be used.
Well, it's quite simple in the end:
When overriding virtual methods, the concrete methods are resolved at runtime.
When using the new keyword (or leaving it out completely), you're doing a static replacement operation at compile time based on the type information that is available in your code.
These are two totally different things.
What you did is method hiding (as others already explained).
If you really want to do it you should add new keyword in method definition to make warning disappear and also as a documentation. So that other developers looking at your code know that you did it on purpose.

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.

How do I block the new modifier?

I have a property in a base class that I don't want overridden for any reason. It assigns an ID to the class for use with a ThreadQueue I created. I see no reason whatsoever for anyone to override it. I was wondering how I can block anyone from attempting to override it short of them changing its modifier.
private int _threadHostID = 0;
public int ThreadHostID
{
get
{
if (_threadHostID == 0)
{
_threadHostID = ThreadQueue.RequestHostID();
}
return _threadHostID;
}
}
Edit: totally forgot the language: C#.
Edit2: It is not virtual or overriding anything else so please no sealed.
First off: "Overriding" refers to virtual overriding. You are talking about creating hiding methods, not overriding methods.
I have a property in a base class that I don't want hidden
You are free to want that, but you are going to have to learn to live with the disappointment of not getting what you want.
I see no reason whatsoever for anyone to hide it.
Then there won't be a problem, will there? If no one could possible want to hide it, then they won't hide it. You're basically saying "I have an object of no value to anyone; how do I keep someone from stealing it?" Well, if it is of no value, then no one is going to want to steal it, so why would you spend money on a safe to protect something that no one wants to steal in the first place?
If there is no reason for someone to hide or override your method then no one will. If there is a reason for someone to hide or override your method, then who are you to tell them not to? You are providing a base class; you are the servant of the derived class author, not their master.
Now, sometimes being a good servant means building something that resists misuse, is robust, and reasonably priced. I encourage people to build sealed classes, for example. Designing secure, robust, inheritable classes that meet the real needs of inheritors is expensive and difficult.
But if you are going to create a robust unsealed base class designed for inheritance, why try to stop the derived class author from hiding, if they have a reason to do so? It cannot possibly hurt the base class. The only people it could hurt are the users of the derived class, and those people are the derived class author's problem, not yours.
There is no way to stop member hiding. If you don't make it virtual or abstract, then a derived class cannot override it properly anyway, hiding isn't polymorphic.
If a derived class hides it using the new operator, then they are opening up problems for themselves as any code that decides to use a reference to the base class will not touch the derived member. So basically, all code that utilises the "base class"-ness of the type hierarchy will bypass all member hiding anyway.
The sealed keyword only works if a derived type overrides a base type and doesn't want it to be overridden further... not sure how it plays with the new operator though. Most likely the member hiding will still be allowed, but will still have the same direct-type problem.
Your task is done by not making the method virtual or abstract, if a person wants to hide members then they are responsible for anything that breaks because they decided to abuse the design.
I think you should not worry about this. If you don't write it as virtual then you are making clear that it is not intended to be overridden and in fact you will receive a warning if you will override it (without the "new" modifier):
Warning: [...] hides inherited member [...].
Use the new keyword if hiding was intended
If you have this fear you should worry about any method that you write in a non-sealed class. So the job for you is just make sure that the design of your class is consistent and clear and if someone wants to inherit it then should be not dumb to just go and redefine non-virtual properties/methods. You cannot completely shield yourself from others stupidity :).
As far as I can tell, you apparently can't do that on a property level. However, if you seal the class:
public class Base
{
public int ID { get; set; }
}
public sealed class Child : Base
{
/// blah
}
then ...
public class Grandchild : Child
{
public int ID { get; set; }
}
will throw an error on the class definition, so using new doesn't even come into play.
Not an exact solution to your problem, but it does keep others from extending or interfering with your API.
Does it actually matter if someone does put a 'new' implementation in? I'm assuming you will always be referring to the base class in any code using that property since that is where it is declared and since it's not override or virtual it won't polymorphically call up to a 'new' implementation anyway.

Why not make everything 'virtual'? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Why C# implements methods as non-virtual by default?
I'm speaking primarily about C#, .NET 3.5, but wonder in general what the benefits are of not considering everything "virtual" - which is to say that a method called in an instance of a child class always executes the child-most version of that method. In C#, this is not the case if the parent method is not labeled with the "virtual" modifier. Example:
public class Parent
{
public void NonVirtual() { Console.WriteLine("Non-Virtual Parent"); }
public virtual void Virtual(){ Console.WriteLine("Virtual Parent"); }
}
public class Child : Parent
{
public new void NonVirtual() { Console.WriteLine("Non-Virtual Child"); }
public override void Virtual() { Console.WriteLine("Virtual Child"); }
}
public class Program
{
public static void Main(string[] args)
{
Child child = new Child();
Parent parent = new Child();
var anon = new Child();
child.NonVirtual(); // => Child
parent.NonVirtual(); // => Parent
anon.NonVirtual(); // => Child
((Parent)child).NonVirtual(); // => Parent
child.Virtual(); // => Child
parent.Virtual(); // => Child
anon.Virtual(); // => Child
((Parent)child).Virtual(); // => Child
}
}
What exactly are the benefits of the non-virtual behavior observed above? The only thing I could think of was "What if the author of Parent doesn't want his method to be virtual?" but then I realized I couldn't think of a good use case for that. One might argue that the behavior of the class is dependent on how a non-virtual method operates - but then that seems to me there is some poor encapsulation going on, or that the method should be sealed.
Along these same lines, it seems like 'hiding' is normally a bad idea. After all, if a Child object and methods were created, it seems that it was done so for a specific reason to override the Parent. And if Child implements (and hides the parents) NonVirtual(), it is super easy to not get the what many might consider "expected" behavior of calling Child::NonVirtual(). (I say "expected" because it is sometimes easy to not notice 'hiding' is happening).
So, what are the benefits of not allowing everything to have "virtual" behavior? What is a good use-case for hiding a non-virtual parent if it's so easy to get unexpected behavior?
If anyone is curious as to why I pose this question - I was recently examining Castle Projects DynamicProxy library. The one main hurdle in using it is that any method (or property) you want to proxy has to be virtual. And this isn't always an option for developers (if we don't have control over the source). Not to mention the purpose of DynamicProxy is to avoid-coupling between your proxied class and whatever behavior you are trying to achieve with the proxy (such as Logging, or perhaps a Memoization implementation). And by forcing virtual methods to accomplish this what is instead achieved is very thin but obtuse coupling of DynamicProxy to all the classes it is proxying - Imagine, you have a ton of methods labeled virtual even though they are never inherited and overridden, so any other developer looking at the code might wonder "why are these even virtual? lets change them back".
Anyway, the frustration there led me to wonder what the benefits are of non-virtual, when it seems having everything virtual might have been more clear (IMO, I suppose) and perhaps(?) have more benefits.
EDIT: Labeling as community wiki, since it seems like a question that might have subjective answers
Because you don't want people overriding methods that you haven't designed the class for. It takes a significant effort to make sure it is safe to override a method or even derive from a class. It's much safer to make it non-virtual if you haven't considered what might happen.
Eric Lippert covers this here, on method hiding
In many cases, it is crucial for a class to function properly that a given method has a specific behavior. If the method is overridden in an inherited class, there is no guarantee that the method will correctly implement the expected behavior. You should only mark a method virtual if your class is specifically designed for inheritance and will support a method with a different implementation. Designing for inheritance is not easy, there are many cases where incorrectly overriding a method will break the class's internal behavior
Simple: The entire point in a class is to encapsulate some kind of abstraction. For example, we want an object that behaves as a text string.
Now, if everything had been virtual, I would be able to do this:
class MessedUpString : String{
override void Trim() { throw new Exception(); }
}
and then pass this to some function that expects a string. And the moment they try to trim that string, it explodes.
The string no longer behaves as a string. How is that ever a good thing?
If everything is made virtual, you're going to have a hard time enforcing class invariants. You allow the class abstraction to be broken.
By default, a class should encapsulate the rules and behaviors that it is expected to follow. Everything you make virtual is in principle an extensibility hook, the function can be changed to do anything whatsoever. That only makes sense in a few cases, when we have behavior that is actually user-defined.
The reason classes are useful is that they allow us to ignore the implementation details. We can simply say "this is a string object, I know it is going to behave as a string. I know it will never violate any of these guarantees". If that guarantee can not be maintained, the class is useless. You might as well just make all data members public and move the member methods outside the class.
Do you know the Liskov Substitution Principle?
Anywhere an object of base class B is expected, you should be able to pass an object of derived class D. That is one of the most fundamental rules of object-oriented programming. We need to know that derived classes will still work when we upcast them to the base class and pass them to a function that expect the base class. That means we have to make some behavior fixed and unchangeable.
One key benefit of a non-virtual method is that it can be bound at compile time. That is the compiler can be sure which actual method is to be called when a method is used in code.
The actual method to be called cannot be known at compile time if that method is declared virtual, since the reference may actually point to a sub-type that has overriden it. Hence there is a small overhead at runtime when the actual method to call needs be resolved.
In a framework, a non-virtual member could be called and have a range of expected outputs, if the method was virtual the result of the method could be an expected result that wasn't tested for. Allowing methods to be non-virtual give expected results to framework actions.

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