2015-04-24 4 views
0

Я не underatnd несколько вещей об этой следующей строкеJava/очередь приоритетов и конструкторы и типа

PriorityQueue<D> myList = new ImplementPriorityQueue<D>(K + 1); 

PriorityQueue<D> является объектом, как целое для Exemple, то есть «PriorityQueue» связанный список (из-за <>), который имеет элементы типа D (D - общий термин). И ImplementPriorityQueue - это конструктор, также связанный список? Но не должен ли объект и и конструктор иметь одно и то же имя?

также, конструктор позволяет вам построить объект и затем использовать функции, написанные в конструкторе? Это правильно?

+0

'PriorityQueue ' является тип переменной. 'ImplementPriorityQueue ' - тип создаваемого объекта. – immibis

+1

это то же самое, что и «Object o =» test ». Сам объект - это просто суперкласс String в этом случае, где' PriorityQueue', кажется, является суперклассом «ImplementPriorityQueue» – SomeJavaGuy

+0

, но <> не означает его Связанный список? –

ответ

0

PriorityQueue - это класс, а не объект.

myList - объект типа PriorityQueue с общим типом D.

ImplementPriorityQueue - фактический тип объекта, в данном случае подкласс PriorityQueue.

new ImplementPriorityQueue<D>(K + 1) вызывает экземпляр объекта, присвоенного myList, используя конструктор с подписями ImplementPriorityQueue(int).

Кстати, почему вы звоните в очередь myList? myQueue может быть менее запутанным.

EDIT В ответ на замечание о MyList с двумя типами ...

PriorityQueue является объявленный тип, и так это то, что ваш код будет относиться к ней как. Он имеет такие методы, как peek, contains и т. Д., И все они доступны для вашего кода.

ImplementPriorityQueue - фактический тип myList. У него могут быть такие методы, как, например, explode, makeIceCream и т. Д., Но ваш код будет , а не, имеют доступ к этим методам, потому что он думает о myList как PriorityQueue - и эти методы не существуют в PriorityQueue.

Это всегда хорошая идея как можно более общая, но не более общая при создании кода. Давайте рассмотрим пример метода, который перебирает список строк и выводит значения.

public void printValues(ArrayList<String> list) { 
    for (String s : list) { 
     System.out.println(s); 
    } 
} 

Вы могли бы назвать этот метод, передавая ему ArrayList:

ArrayList<String> list = new ArrayList<>(); 
printValues(list); 

Это будет работать нормально ... но что, если у вас также есть LinkedLists в вашем коде? Следующий код не будет компилироваться, потому что printValues ожидает ArrayList.

LinkedList<String> list = new LinkedList<>(); 
printValues(list); <--- compilation error here 

Способ разработки для этого заключается в использовании более общей версии как ArrayList, так и LinkedList. Оба этих класса расширяют AbstractList, поэтому мы можем изменить его на это.

public void printValues(AbstractList<String> list) { 
    for (String s : list) { 
     System.out.println(s); 
    } 
} 

Теперь мы можем передать ему LinkedLists, ArrayLists и все остальное, что расширяет AbstractList. Однако, мы можем улучшить это дальше, потому что AbstractList - это действительно деталь реализации. Мы действительно заботимся о списках, и поэтому мы действительно должны смотреть на интерфейс, который определяет поведение типа List. Это java.util.List, и наша окончательная версия метода выглядит так.

public void printValues(List<String> list) { 
    for (String s : list) { 
     System.out.println(s); 
    } 
} 

Теперь, потому что мы работаем с определением и не фактический типа мы имеем намного более полезный метод, который будет принимать все, что реализует List.

Это поведение называется полиморфизмом - мы можем рассматривать объект типа A как объект типа B, если между ними существует родительско-дочерняя связь. Вот почему вы можете рассматривать что-либо как объект, потому что Object является родителем всего.

Что касается вещей как можно более общих, но не более того - List является таким же общим, как вы можете получить для списков. Вы бы не сказали, например, «ну, объект еще более общий!».

+0

, но почему myList имеет два типа PriorityQueue и ImplementPriorityQueue? это как сказать, что объект является строкой и двойной для примера ... я не понимаю эту часть. –

+0

myList имеет объявленный тип, который является «PriorityQueue» и фактическим типом, который является «ImplementPriorityQueue». Я уточню свой ответ для деталей. –

+0

так что 'ImplementPriorityQueue' является своего рода подтипом' PriorityQueue'? –

0

От Javadocs:

Casting показывает использование объекта одного типа вместо другого типа, среди объектов разрешенных наследования и реализаций. Например, если мы пишем

Object obj = new MountainBike(); // or Object obj = new String(); 

затем OBJ не является как объект и MountainBike (или строка для последующего случая) - до тех пор, пока OBJ назначен другой объект, который не является MountainBike. Это называется неявное литье.

В другом примере, кроме обычного способа:

Child c = new Child(); // or Parent p = new Parent(); 

мы также можем использовать (отклонение от курса в соответствии с нашим требованием)

Parent p = new Child(); 

Здесь Child класса может быть расширение Parent класса или любой из его подклассов. Примечание - в этом случае Polymorphism вступает в действие, и применяются обычные правила.

+0

, но в этом примере есть 'public MountainBike myBike = new MountainBike();'; но не можем ли мы поместить 'public Bycicle myBike = new MountainBike();' и это означало бы то же самое, потому что MountainBike является подклассом Bycicle? Точно так же, как здесь, мы не можем поставить 'ImplementPriorityQueue myList = new ImplementPriorityQueue (K + 1);'? –

+0

Конечно, мы можем написать. В принципе, вам нужно пройти через Полиморфизм и Наследование от Javadocs. Также я отредактировал свой ответ. –

+0

, но здесь, на данный момент, в вашем примере p = c нет? по крайней мере, мы можем сказать, что они представляют собой один и тот же объект с одним и тем же типом? –

0

Это называется полиморфизмом, Java использует наследование для определения подклассов друг друга, чтобы обеспечить согласованность во всех классах. В этом случае PriotityQueue является объявленным типом, а OptionPriorityQueue - экземпляром, которому присвоено это объявление. Это обеспечивает гибкость при использовании функции «Реализация».

например - An ArrayList может быть создан как в этом списке Collection

= новый ArrayList();

Это потому, что arraylist расширяет класс коллекции. Это, в свою очередь, помогает вам кодировать, позволяя вам позднее изменять версии списков.

например

Коллекция = новый LinkedList();

Это будет держать весь код от прежде, чем в соответствии с LinkedList в связи с предыдущим ArrayList ограничившись правилам сбора

+0

так в основном, используя «Collection», позволяет мне изменить букву «объект» объекта «объект» от arraylist на связанный список juste, потому что связанный список является частью коллекции суперкласса? –

+0

Объект может быть создан в Декларации любого суперкласса выше и включает в себя сам. E.G String является подклассом Object. Таким образом, строка может быть создана как этот Object str = new String («JAVA»); – Shifty

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