Let’s say you have some Java code as follows:
public class Base{
public void m(int x){
// code
}
}
and then a subclass Derived, which extends Base as follows:
public class Derived extends Base{
public void m(int x){ //this is overriding
// code
}
public void m(double x){ //this is overloading
// code
}
}
and then you have some declarations as follows:
Base b = new Base();
Base d = new Derived();
Derived e = new Derived();
b.m(5); //works
d.m(6); //works
d.m(7.0); //does not compile
e.m(8.0); //works
For the one that does not compile, I understand that you are passing in a double into Base’s version of the m method, but what I do not understand is… what is the point of ever having a declaration like “Base b = new Derived();” ?
It seems like a good way to run into all kinds of casting problems, and if you want to use a Derived object, why not just go for a declaration like for “e”?
Also, I’m a bit confused as to the meaning of the word “type” as it is used in Java. The way I learned it earlier this summer was, every object has one class, which corresponds to the name of the class following “new” when you instantiate an object, but an object can have as many types as it wants. For example, “e” has type Base, Derived, (and Object 😉 ) but its class is Derived. Is this correct?
Also, if Derived implemented an interface called CanDoMath (while still extending Base), is it correct to say that it has type “CanDoMath” as well as Base, Derived, and Object?
There are a number of cases where confining yourself to a particular (sub)class is not desired, such as the case you have where
e.m(8.0);. Suppose, for example, you have a method calledmovethat moves an object in the coordinate graph of a program. However, at the time you write the method you may have both cartesian and radial graphs, handled by different classes.If you rely on knowing what the sub-class is, you force yourself into a position wherein higher levels of code must know about lower levels of code, when really they just want to rely on the fact that a particular method with a particular signature exists. There are lots of good examples:
In these situations, you simply want to ensure the object has a particular type, which guarantees that particular method signatures are available. In this way your example is contrived; you’re asking why not just use a class that has a method wherein a double is the signature’s parameter, instead of a class where that isn’t available. (Simply put; you can’t use a class that doesn’t have the available method.)
There is another reason as well. Consider:
Note that in the
bcase, I do not have access to the methodset()and thus can’t muck up the super sensitive variable accidentally. I can only do that in theecase. This helps make sure those things are only done in the right place.Your definition of type is good, as is your understanding of what types a particular object would have.