2014-09-12 76 views
0

我见过用于超类型变量的子类的constructer方法。例如:超类型对象的子类的构造方法?

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

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

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

http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html – sp00m 2014-09-12 15:01:41

回答

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

Java实例的类型由用于创建它的构造函数确定,并且无法更改。

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

类型用于引用一个实例的变量的可以仅:

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

作为变量的类层次结构越高,使用它的代码越通用(因此可重用)。作为设计规则,您应该使用接口作为变量(特别是参数)类型。

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

+0

所以它基本上与'SimpleDateFormat formatter = new SimpleDateFormat(“yyyy-MM-dd”)''一样吗? “DateFormat”与其子类的构造函数声明的点是什么? – ddd 2014-09-12 15:08:37

+0

@nasreddin完全一样;将它首先声明为'DateFormat'没有任何好处 – msrd0 2014-09-12 15:09:19

0

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

SimpleDateFormat接入方式,你可以将它转换:

SimpleDateFormat sdf = (SimpleDateFormat) formatter; 

这只只要formatterSimpleDateFormat类型或它的任何子类的工作。下面的行会产生一个编译错误:

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

顺便说一句,我只想宣布formatter从一开始就SimpleDateFormat。您将它声明为DateFormat并没有任何好处,并且比铸造它 - 这是对您的CPU的浪费。