Reputation: 5029
I have seen constructer method of subclass being used for a variable with superclass type. For example:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Is formatter
a DateFormat
type object or a SimpleDateFormat
type? Since the class SimpleDateFormat
inherit from DateFormat
, it probably has more methods than its superclass. Can the instance formatter
call these functions only exist in SimpleDateFormat
but not DateFormat
? Are DateFormat
and SimpleDateFormat
interchangeable in this case? such as:
SimpleDateFormat formatter = new DateFormat ("yyyy-MM-dd");
Upvotes: 0
Views: 197
Reputation: 10725
The type of a Java instance is determined by the constructor used for creating it, and cannot be changed.
The methods that may be invoked on an instance, depend on the type of the variable used to reference it. Therefore, you may invoke different sets of methods over the same instance, depending on the type of the variable you use to reference it.
The type of the variable used to reference an instance ONLY may be:
The higher in the class hierarchy that is the variable, the more general (and therefore, reusable) is the code that uses it. As a rule of design, you should use Interfaces as variable (and specially parameter) types.
Suggest you to read this: http://en.wikipedia.org/wiki/Liskov_substitution_principle
Upvotes: 1
Reputation: 25980
The runtime type of formatter
is determined by the constructor used to instantiate it, and its compile-time type is the one you used in the declaration. You cannot call a method on formatter that would exist on its actual runtime type and not on its declaration type, unless you use a cast to resolve the method call.
By the way, you could have answered your own questions by simple experiments :
public class SuperClass {
public void test() {
System.out.println("Test");
}
public static class SubClass extends SuperClass {
public void testSub() {
System.out.println("Test sub");
}
@Override
public void test() {
System.out.println("Override test");
}
}
public static void main(String[] args) {
SuperClass sc = new SuperClass();
sc.test(); // prints Test
sc = new SubClass();
sc.test(); // prints Override test
sc.testSub(); // does not compile
((SubClass) sc).testSub(); // prints Test sub
}
}
Upvotes: 3
Reputation: 8390
formatter
is of both types, DateFormat
and SimpleDateFormat
. As soon as you call the constructor for SimpleDateFormat
, it also calls the constructor for DateFormat
- but it is only one Object.
To access methods from SimpleDateFormat
, you can cast it:
SimpleDateFormat sdf = (SimpleDateFormat) formatter;
This only works as long as formatter
is of type SimpleDateFormat
or any subclass of it. The following line will produce an compile error:
SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateTimeInstance();
By the way, I would just declare formatter
as a SimpleDateFormat
from the beginning. You have no benefit from declaring it as a DateFormat
and than cast it - this is a waste of your CPU.
Upvotes: 0