超类型对象的子类的构造方法?

时间:2014-09-12 14:59:43

标签: java class date inheritance constructor

我已经看到子类的constructer方法用于具有超类类型的变量。例如:

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

formatterDateFormat类型对象还是SimpleDateFormat类型?由于类SimpleDateFormat继承自DateFormat,因此它的方法可能比其超类更多。实例formatter调用这些函数只能存在于SimpleDateFormat但不存在DateFormat吗?在这种情况下,DateFormatSimpleDateFormat是否可以互换?如:

SimpleDateFormat formatter = new DateFormat ("yyyy-MM-dd");

3 个答案:

答案 0 :(得分:3)

formatter的运行时类型由用于实例化它的构造函数确定,其编译时类型是您在声明中使用的类型。除非使用强制转换来解析方法调用,否则不能在格式化程序上调用其实际运行时类型而不是其声明类型的方法。

顺便说一句,你可以通过简单的实验回答你自己的问题:

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
    }
}

答案 1 :(得分:1)

Java实例的类型由用于创建它的构造函数确定,不能更改。

可以在实例上调用的方法取决于用于引用它的变量的类型。因此,您可以在同一实例上调用不同的方法集,具体取决于您用于引用它的变量的类型。

用于引用实例的变量类型可能是:

  • 相同类型的引用实例
  • 引用实例类型的超类
  • 由参考实例的类型实现的接口。

作为变量的类层次结构中的较高者,使用它的代码越通用(因此可重用)。作为设计规则,您应该使用Interfaces作为变量(和特殊参数)类型。

建议你阅读:http://en.wikipedia.org/wiki/Liskov_substitution_principle

答案 2 :(得分:0)

formatter属于DateFormatSimpleDateFormat两种类型。一旦调用SimpleDateFormat的构造函数,它也会调用DateFormat的构造函数 - 但它只是一个Object。

要从SimpleDateFormat访问方法,您可以投射它:

SimpleDateFormat sdf = (SimpleDateFormat) formatter;

只有formatter类型为SimpleDateFormat或其任何子类时,此方法才有效。以下行将产生编译错误:

SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateTimeInstance();

顺便说一句,我只是从一开始就将formatter声明为SimpleDateFormat。将它声明为DateFormat而不是施放它没有任何好处 - 这会浪费你的CPU。