2014-09-12 4 views
0

Я видел метод конструктора подкласса, который используется для переменной с типом суперкласса. Например:Метод конструктора подкласса для объекта типа суперкласса?

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

Является formatterDateFormat объект типа или SimpleDateFormat типа? Так как класс SimpleDateFormat наследует от DateFormat, он, вероятно, имеет больше методов, чем его суперкласс. Может ли экземпляр formatter назвать эти функции только в SimpleDateFormat, но не DateFormat? Есть DateFormat и SimpleDateFormat сменный в этом случае? такие как:

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

http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html – sp00m

ответ

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 определяется конструктор, используемый для создания, и не может быть изменен.

Методы, которые могут быть вызваны в экземпляре, зависят от типа переменной, используемой для ее ссылки. Поэтому вы можете ссылаться на разные наборы методов в одном экземпляре, в зависимости от типа переменной, которую вы используете для ее ссылки.

тип переменной, используемой для ссылки на экземпляр ТОЛЬКО может быть:

  • Тот же тип ссылочного экземпляра
  • суперкласс типа ссылочного экземпляра
  • Интерфейс реализован тип ссылочного экземпляра.

Чем выше иерархия классов, являющаяся переменной, тем более общим (и, следовательно, повторно используемым) является код, который ее использует. Как правило, вы должны использовать Interfaces в качестве переменных (и специально для них).

Предлагаем Вам прочитать: http://en.wikipedia.org/wiki/Liskov_substitution_principle

+0

, так что это по существу то же самое, что и для 'SimpleDateFormat formatter = new SimpleDateFormat (" yyyy-MM-dd ")'? Что такое точка объявления с «DateFormat» с конструктором подкласса? – ddd

+0

@nasreddin Это точно так же; и нет никакой выгоды объявить его как «DateFormat» первым – msrd0

0

formatter имеет обоих типов, DateFormat и SimpleDateFormat. Как только вы вызываете конструктор для SimpleDateFormat, он также вызывает конструктор для DateFormat - но это только один объект.

доступа к методам из SimpleDateFormat, вы можете бросить его:

SimpleDateFormat sdf = (SimpleDateFormat) formatter; 

Это работает только до тех пор, как formatter имеет тип SimpleDateFormat или любого подкласса этого.Следующая строка выдаст ошибку компиляции:

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

Кстати, я бы просто объявить formatter как SimpleDateFormat с самого начала. У вас нет никакой пользы от объявления его как DateFormat, а не его литья - это пустая трата вашего процессора.

Смежные вопросы