public abstract class Duck
{
public Duck()
{
}
public abstract void display();
}
An abstract class will have a method that will be an abstract method. This means a child class that will inherit from "Duck" will have the same abstract method called "Display"
public class Mallack:Duck
{
public Mallack()
{
}
public override void display()
{
}
}
The Mallack is a child class that inherits from Duck. Remember all clases that will inherit from Duck will have the method "display"
Hope it helps...
Updated 22-Mar-12 21:52pm
v2
Apparently, if you know what is that, you know that you cannot instantiate such class. You also should know, that if you have a single abstract method or property (which is always virtual and without implementation), the syntax will force you to declare the whole class as abstract.
Now, let's speculate logically. If you cannot create the class instance, what you can do? You can create some derived classes of this abstract class. Some derived classes can be abstract, but ultimately you will need to create some terminal classes which are not abstract and can be instantiated, otherwise the whole activity could be useless.
So, you abstract class would be the abstract base for all the hierarchy. And the non-abstract classes from the hierarchy should override all abstract methods/properties, otherwise you would not be able to make them non abstract. The methods will be dynamically dispatched through the mechanism of virtual method table, which is the essence of late binding.
Now, you should understand the difference between run-time and compile-time types. You can declare a variable of any type, including the abstract class. When you instantiate the variable, its run-time type could not be of the abstract class (remember, it cannot be instantiated), so its run-time type should be different from compile-time type, and should be one of the derived classes, and only of a non-abstract one. When you call an abstract method (from the standpoint of the compile-time), the dynamically dispatched run-time method will always be the one implemented in the derived class, always non-abstract one. Why? Because 1) you cannot have an abstract method in a non-abstract class, 2) you cannot instantiate a non-abstract class. The call will always be properly resolved.
Same thing will happens with a polymorphous set. The compile-time type can be an abstract class (for example, the actual generic parameter of System.Collections.Generic.List
), but all run-time types of the objects actually added to this container… yes, as described in the previous paragraph.
So, everything works for late binding and polymorphism
. Now, the question is: could it work of we never used abstract class. Yes, it would work in the exact same way. Only we would need to implement all the methods which would otherwise be abstract using the keyword virtual
instead. For example, such methods would have empty bodies (we would need some bodies anyway, if we want them non-abstract). Usually such methods are called pseudo-abstract. What would be wrong with that?
The answer is: nothing wrong but — declaring abstract class would work as a fool-proof feature. A pseudo-abstract methods are only good if they still could participate in normal functionality. For example, a pseudo-abstract method ShowMessage
could show nothing "by default", but this could be customized in derived classes. But there are more cases where having no certain definitive behavior of one or more method would really screw up the functionality without some specific implementation. Hence, an accidental instantiation and use of such object could screw up the functionality of the system.
Without abstract classes, what could be done? (Yearly OOP languages really did not have them.) We could explain that this and this class (such as System.IO.Stream
) should never be instantiated and is only used as a base of the following classes… and also user-defined classes, and list them — in documentation. But preventing such accidental misuse just by syntax is much better.
You can find many examples of abstract classes in the libraries which come with .NET and placed in GAC. Try to think about their use; and you will clearly understand it.
—SA