package geometry;
public abstract class Shape
{
abstract double area();
}
public class Rectangle extends Shape
{
private double length;
private double width;
double area()
{
return length * width;
}
}
In class Shape, we declared a method area, and we implemented it in Rectangle.
package geometry;
public abstract class Shape
{
double area();
}
public class Rectangle extends Shape
{
private double length;
private double width;
area()
{
return length * width;
}
}
There are only two differences:
area method in class Shape does not need the abstract keyword. It is obvious, from the fact that the is no implementation of area in class Shape.
area in Rectangle does not mention the return type double. This type is already known from the declaration of the method (and the compiler will check that the returned value has really type double).
overlap that has two Shape arguments.
package my.package;
import geometry.*;
class Tools
{
static boolean overlap(Shape s1, Shape s2)
{
if (s1 instanceof Rectangle && s2 instanceof Rectangle)
{
...
// return the result in this case
}
throw new Error("Case not supported: " + s1.getClass() + " and " + s2,getClass());
}
}
Not very pretty. And this solution has three fundamental problems:
instanceof to decide which code to execute. In that code, you will need to cast s1 and s2 to class Rectangle. Calling this method will look akward: Tools.overlap(s1, s2) instead of s1.overlap(s2).
Shape, you will need to edit the source of Tools to handle that new case. If this is done by a user of your code who cannot change the source, it is simply impossible to do that, so extensibility is blocked.
Shape. This is something very simple and natural to do in Nice:
package my.package;
import geometry;
// We declare a new method, that has two arguments.
boolean overlap(Shape s1, Shape s2);
// Here is the code for overlap, when both arguments are rectangles
overlap(Rectangle s1, Rectangle s2)
{
// Here s1 and s2 are both rectangles. We don't need to use instanceof or cast.
...
// return the result
}
This solution solves all three problems:
s1.overlap(s2), as if overlap had been declared in class Shape.
Shape, you can simply add new implementations for the new cases that it belongs to. This can be done anywhere, including in a different package.
this, or self) is used. This is important here, since we cannot decide if a rectangle overlaps with an arbitrary shape.
area as an external method, instead of declaring it inside the class. Both forms are stricly equivalent. It is a matter of style to decide which one to use in that case.
-- DanielBonniot - 30 May 2003
| Topic FunctionsAndMethods . { Edit | Attach | Ref-By | Printable | Diffs | r1.7 | > | r1.6 | > | r1.5 | More } |
|
Revision r1.7 - 25 Jan 2004 - 21:37 GMT - TWikiGuest Parents: WebHome > NiceTutorial |
Copyright © 1999-2003 by the contributing authors.
All material on this collaboration platform is the property of the contributing authors. Ideas, requests, problems regarding TWiki? Send feedback. |