ddd
ddd

Reputation: 5029

Constructor method of subclass for a superclass type object?

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

Answers (3)

Andres
Andres

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 same type of the referenced instance
  • A superclass of the type of the referenced instance
  • An interface implemented by the type of the reference instance.

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

Dici
Dici

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

msrd0
msrd0

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

Related Questions