Abstract methods and hiding methods - c#

I'm trying to understand abstract classes in c# better.
I know that in abstract classes you MUST override abstract methods and MAY override virtual methods..
my question is:
can I override non virtual methods? (I know that normally I can't - but maybe with abstract classes it's different?) or will it be like hiding ?
also, as I read here How to force call a C# derived method (the first answer) - it seems to me that because non virtual methods statically linked at compile time and can't be changed - I would not be able to call the methods in the derived class ,never? if so - what is the point of hiding a method?

I'm trying to understand abstract classes in c# better.
OK, then lets correct your mistakes, because you have some completely wrong ideas about abstract classes here.
I know that in abstract classes you MUST override abstract methods and MAY override virtual methods.
Absolutely not; the first part of that sentence is completely wrong. There is no requirement whatsoever in an abstract class to override an abstract method.
A non-abstract class is called a concrete class. The real rules are:
A concrete class must override all abstract methods of all its abstract base classes with concrete methods; it can do so either itself, or via one or more of its base classes.
This should make sense: you can't make an instance of a concrete class until every abstract method is implemented; otherwise you could invoke a method that has no implementation, and that would be bad.
Any derived class may override a non-sealed virtual method of any of its base classes.
can I override non virtual methods?
No. You can overload non-virtual methods and you can hide existing non-virtual methods, but you cannot override them.
it seems to me that because non virtual methods statically linked at compile time and can't be changed - I would not be able to call the methods in the derived class ,never?
Of course not. You call the methods of the derived class by converting the receiver to the derived class.
what is the point of hiding a method?
Duplicate of:
Is method hiding ever a good idea
Here's a BONUS QUESTION that you did not ask. See if you can answer it.
Can a method be marked as both abstract and override? If no, why not? If yes, give an example and explain why you would want to.
If you can answer that question correctly then you probably have a good understanding of abstract methods. The solution is here.

No, you can't. They must have virtual keyword. Good example here,similarThis one as well

I would advise taking a closer look into what you can do with OOP
In reference to your question, you can only override a virtual class, another of example instead of hiding methods would be:
However you can use inheritance, to use the controls from your base class. This should be done when both classes are related, to prevent creating duplicate code.
An example of this would be an individual person : Human, okay so here we use ('type of' :) stating that a person is a type of human. This is the basic use of inheritance.
This shouldn't be done if they are not related, this may seem quicker when you are doing it, however when you look back at your application 3months on you will say "Why did I do that?".
An example of this would be, this base class has a method close to what I am looking for, you need to make a comparison, is it Really? Should I actually do this?
The msdn article provided will give you the information you need to progress with this. Enjoy OOP

You have a little misunderstanding:
in abstract classes you MUST override abstract methods and MAY override virtual methods.
That sentence should really be:
in concrete classes that derive from an abstract class, you MUST override abstract methods and MAY override virtual methods, either in that class itself, one of its parent classes, or one of its subclasses.
You can use the new keyword to shadow, or hide, non-virtual methods, so yes it will be hiding and not overriding.
If you hide a method in a subclass, and then want to call the method as it appeared in the base class, cast the subclass as the to the base class type, as done in the second example here.

Related

C# - when do I need override? When don't I need it?

I am using C# with Unity3d.
When I use Monobehaviour and create an Update method, I don't need to use the override keyword.
When I create my own class and override a function, I do need to use the override keyword.
Why is that? Why do I not need the override keyword when creating the Update method?
I think your confusion comes from the fact that Unity does something special about these methods (Update, Start, Awake, etc). You can declare them as private and even then they will be called. That's not achievable using the language unless you use reflection, but I was told they don't use it, so I don't know what they do. And honestly, it doesn't matter. Because you can think as this being an exception to the language, that is, these methods will be called if you implement them. Simply that.
For all the rest, you have to follow the language. Here is a rough explanation:
You can or have to override a method if it is marked as abstract or virtual in the base class.
A method is abstract when the base class wants its children to implement it. A method is virtual when the base class offers an implementation of it but also offers an opportunity for the children to implement/modify that method.
So why can't all methods be "overridable"? To protect the base class developer's intention. You'd be changing the behaviour of a base class, you don't know if the base class developer would like you to do this. It's like a security lock. So that's why you have the three words abstract, virtual and override, to communicate the API intentions from the base class to their children.
You need to use the override, when you derive a class from another class and you need to change the code of a method of the base class that is virtual. This way the inheritted method of the base class can have a different behaviour -more suitable- for the derived class.
More generally, as it is stated in MSDN:
The override modifier is required to extend or modify the abstract or virtual implementation of an inherited method, property, indexer, or event.

why do I need "sealed" method if "virtual" is required in order to allow derived class override it?

or am I missing something basic here??..
since sealed method avoids it to be overridden in the derived class and virtual allows it to
sealed is for preventing a subclass from overriding virtual methods you overrode.
The virtual keyword will let you (or someone using your code) override a given method with their own logic.
The abstract keyword will force you (or someone else using your code) to override it with your own logic.
The sealed keyword will let you (or someone using your code) prevent any further modification of a method.
An overriden method can be overriden again if you don't add "sealed".
When you think of these keywords, think of both scenarios: you can code for yourself, or you can create DLLs and code libraries for others to use. The latter scenario will often warrant the use of sealed, abstract and virtual.
Hope this helps!
Methods do not to be sealed or virtual. You do not need to specify anything, which will in turn not let derived classes override them.
Methods can me virtual, but only classes can be sealed.
Sealed classes can not be inherited from.
Source:
http://msdn.microsoft.com/en-us/library/88c54tsw(v=vs.71).aspx
EDIT:
Ok, I was wrong, a method can be sealed, but only one that already overrides another, the keyword then prevents further overriding of the method.
Source:
http://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx

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.

Can abstract classes have implementation in c#?

The compiler doesn't seem to mind it so far but I just wanted to double check whether I'm setting myself up for failure in any way by implementing certain methods in my abstract class.
An abstract class usually has one or more abstract method. So yes it can have some method implemented. The goal is to force the user to implement these methods to have an object working. Sometimes abstract classes are used to provide a 'base' implementation of some interfaces, leaving the final user to specify just the key methods. You can also have an abstract class without any abstract method: in this case you are asserting you must derive from that class in order to use it.
It's common to have some implementation in abstract classes.
If there is no implementation at all, consider using an interface instead of an abstract class.
Perfectly fine to implement some methods and leave others abstract.
If all methods had to be abstract, you might as well use an interface for it.
Yes. abstract class cannot be instantiated (you have to instantiate a class that inherits from your abstract class), but it can contains implementations.
it's fine and allowed, an abstract class has at least a member (method/property) not implemented so it cannot be instantiated.
an interface is also called pure abstract class which means it's 100% abstract, so does not allow you to specify any implementation.
keep in mind that there are lots of articles and opinions about never deriving a concrete class from another concrete class but only from abstract ones... at least this was the trend in C++ up to some years ago, then I moved to the C# side, started working more and had no time to keep reading those nice articles... :)

Should a base class be marked abstract if there are no abstract members?

Is it okay for a class to be marked as abstract if it has no abstract members? Even if there is no practical reason for to directly instantiate it? (aside from unit tests)
Yes, it is reasonable and beneficial to mark explicitly as abstract a base class that should not be instantiated -- even in the absence of abstract methods.
It enforces the common guideline to make non-leaf classes abstract.
It prevents other programmers from creating instances of the class. This may make it easier for you to add abstract methods to it later.
Do you want that class to ever have an actual instance? If yes, then don't mark it abstract. If no, then mark it abstract.
Short answer: yes.
Long answer: The abstract keyword marks a class and/or its members as not being useful directly. Why this may be varies from case to case; an abstract class may be too basic to do any real work, or it may have abstract members that are required to exist for other code in this class to work, but cannot be concretely defined at this level. The short of it is that by marking a class abstract, you tell the compiler and other developers not to instantiate this class directly, but instead to inherit from it to create a concrete useful implementation. You can do this even if the class has a working implementation for all its members, if you feel that the class must be inherited to make the best use of that implementation.
If the goal is to make a base class that other classes will extend, it makes sense to make this an abstract class.
If, however, the goal is to make some form of Utility class -- one that has only static members -- the best way to handle this is to give the class a single constructor marked private. That way, the class can not be instantiated, nor subclassed. This sends a clear signal that the only use of the class is to use its static methods. (This is a tip from Effective Java, by Josh Bloch)
Yes, I think so. At least that's what I do from time to time ;-)

Categories