Loading...
VenelinGrozev avatar VenelinGrozev 130 Точки

[Technical Issue] Java OOP subtyping

Здравейте,

Имам малък проблем с разбирането на subtyping-a при Java List-вете. Става въпрос за първа задача от домашното. Пускам по-долу скелета на класовете

public class Vertex2D {
    private double x;
    private double y;
}

public class Vertex3D extends Vertex2D {
    private double z;
}

public abstract class Shape {
    protected List<? extends Vertex2D> vertices;

    public Shape() {
    }

    public Shape(List<? extends Vertex2D> vertices) {
        this.vertices = vertices;
    }
}

public class PlaneShape extends Shape {
    private Vertex2D vertex;

    public PlaneShape(Vertex2D vertex) {

        this.vertices = new ArrayList<Vertex2D>();
        this.vertices.add(vertex); // compile error
        // The method add(capture#2-of ? extends Vertex2D)
        // in the type List<capture#2-of ? extends Vertex2D>
        // is not applicable for the arguments (Vertex2D)
    }
}

Не мога да разбера защо при инициализация на конструктора на PlaneShape въпреки, че this.vertices става new ArrayList<Vertex2D>() не мога да вкарам в него променлива от тип Vertex2D.

В същото време това решение по-долу работи без проблем

public PlaneShape(Vertex2D vertex) {

        List<Vertex2D> verticesArray = new ArrayList<Vertex2D>();
        verticesArray.add(vertex);
        this.vertices = verticesArray;
    }

 

Явно, че пропускам нещо но не мога да разбера какво, затова всякаква помощ е добре дошла.

Тагове:
0
C# OOP Basics
RoYaL avatar RoYaL Trainer 6849 Точки

Ами отговорът ти го има в документацията на Java :)

http://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html

Consider the following code:

List<EvenNumber> le = new ArrayList<>();
List<? extends NaturalNumber> ln = le;
ln.add(new NaturalNumber(35));  // compile-time error

Because is a subtype of , you can assign to . But you cannot use to add a natural number to a list of even numbers. The following operations on the list are possible:

  • You can add .
  • You can invoke .
  • You can get the iterator and invoke .
  • You can capture the wildcard and write elements that you've read from the list.

You can see that the list defined by is not read-only in the strictest sense of the word, but you might think of it that way because you cannot store a new element or change an existing element in the list.

 

По-скоро това ти трябва като документация де : http://docs.oracle.com/javase/tutorial/java/generics/subtyping.html

Де факто конкретната импелментация после, където казваш че е равно на ArrayList ще трябва да е subtype на типа.

 

0
20/02/2015 13:20:51
VenelinGrozev avatar VenelinGrozev 130 Точки

ROYAL, четох го този пример вчера но той не покрива случаят, който съм описал.

В примера имаме два класа NaturalNumber и EvenNumber - NaturalNumber е по-големият от EvenNumber и при това положение е нормално долните два реда да връщат грешка

List<? extends NaturalNumber> ln = new ArrayList<EvenNumber>();
ln.add(new NaturalNumber(35));

Т.е. не можем да сложим обект от родителският тип в лист от типа на наследника.

В моят случай обаче това не е така, защото имаме

protected List<? extends Vertex2D> vertices = new ArrayList<Vertex2D>(); //направи List в който можем да сложим обекти от тип Vertex2D или от неговите наследници.
this.vertices.add(Vertex2D vertex); //сложи обект от тип Vertex2D в List  в който можеш да слагаш обекти от тип Vertex2D или негови наследници. Връща compile error.

В моят пример поне аз не виждам конфликт в йерархията на класовете.

0
20/02/2015 14:29:35
KevanyTrump avatar KevanyTrump -4 Точки

Нямам нищо във Vertex; Просто го създадох като абстракция, която да използвам във Shape. Не харесвам празни класове, но това е заобиколно решение.

-1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.