Hi,
I think you're misunderstanding the concept of abstract. Let's say that you are writing a system that represents shapes, and you want other programmers in the future to be able to add their own shapes for their own little plugins (say it's a drawing program, like Photoshop). So you'll have a rectangle class, a circle class, a trapezoid, etc. If you just implement these shapes as classes, you can't treat them all simply as shapes, and this is a problem because if someone adds a shape in the future your code won't be able to deal with it without you modifying your code.
So, the solution is you create an abstraction. You do this be writing an abstract class called Shape, and have all your shapes extend from it. What is an abstract class? That way, if someone adds an Octagon class in the future, your code won't know or care because it'll only be dealing with Shapes wherever it doesn't need to know about one of your specific shapes.
Ok, so what's this Shape class look like? Well, we COULD make it an interface, but there's lots of stuff we'd have to write over and over again in every class that implements it (this is not the deciding factor, by the way, concerning whether to make things abstract classes or interfaces). So let's start.
First, we need it to keep track of how many sides this shape has. A quick sanity check: a circle has 1 side, rectangles and trapezoids 4...even an irregular, crazy shape has some number of sides at instantiation time. So version one looks like this:
Next, all shapes have area, and (say) we want to require that everyone who adds their own shape in the future supports this area functionality. And, just like numSides, why not write the code for them too? Here we go...
When we try to write it, we discover that the method of calculating the area is dependent on each different kind of shape, and at the level of the Shape abstraction we don't know what kind of shape this method will be called on (heck, we don't even know what shapes a future programmer will add to the program). So what to do?
Simple, we make it abstract and defer the implementation of this particular method, which is different for each subclass, to those subclasses. But by putting it at this level we ensure that every shape (now and future) must expose its area as a property. So we write instead of the above method:
Now, think about whether it would ever make any sense to instantiate the Shape class directly? How can your program ever deal with an object of type Shape, but not a more specific *kind* of shape? And how could that thing ever live up to its stated contract by providing you with an area property? Fact is, it can't.
Now let's say that you come along as a programmer later on, and decide you want to provide some new shape to the system in a plugin. It turns out there's some class somewhere that you can extend for your plugin, but you have to hand back to the base system the new shape you're dealing with. Well, you know that the base system could never deal with your shape directly--it doesn't know about your new shape, that's why you have to write a new shape in the first place. Now, let's also say that your plugin itself only cares about one particular aspect of this new shape, let's say that it is a
unit shape (of area one), and as far as your plugin is concerned, the user could create a 10-sided shape or a 2-sided shape, your plugin will restrict its area, though, to 1.
You could extend Shape with a UnitAreaShape class if you wanted to, but your plugin doesn't really deal with this thing anywhere as anything but Shape. And no one's ever going to write a plugin for your plugin, so you don't have to worry about extensibility. Instead of cluttering your software with another unnecessary class to maintain, you can create an anonymous class that extends Shape with the properties you want without specifying a class name.
So, let's say your at the point in the code where the user has just input the number of sides this unit area shape should have, and you're ready to have the plugin create it and hand it back to the base system. Here's how you'd do that:
Though you didn't say "extend" anywhere, you've now created an anonymous class that does extend Shape, implemented the one abstract method, created an instance of this new subclass (with numSides going up to the constructor of the parent class). You're done.
sev