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
Filkolev avatar Filkolev 4482 Точки

С такива геометрични задачи наследяванията са доста сложни като логика. В случая триизмерната точка наследява двуизмерната, което е спорно. Има две решения да изчистиш логиката, за които се сещам.

1) Да направиш абстрактен клас за точките и двуизмерните и триизмерните да го наследяват, при което Shape ще приема списък от Vertex, а вече наследниците на Shape ще конкретизират какви точно точки приемат. Аз така подходих.

2) Shape да е празен клас, т.е. да няма списък с точки, евентуално да имплементира интерфейса AreaCalculatable, понеже всички фигури могат да си смятат лицето. 

Не съм сигурен какъв е проблемът, може би "? extends Vertex2D" очаква наследник на Vertex2D, но не приема самия Vertex2D? Не съм ползвал този синтаксис.

0
VenelinGrozev avatar VenelinGrozev 130 Точки

В началото и аз направих абстрактен клас Vertex но се оказа, че няма нужда от него, понеже не знам какво да държа вътре. Реално в основният клас Vertex имам координати х и у, защото това е минимума с който можеш да опишеш една точка. После имаш нужда от още един клас за 3D точките, който да има и още една координата z. Какво държиш в базовият клас Vertex?

Това, че Shape класа ще имплементира AreaCalculatable не помага много. Имам предвид, че - да, трябва да имплементира AreaCalculatable но това не помага да си реша проблема.

List<? extends Vertex2D> значи - направи List в който можеш да слагаш само обекти от тип Vertex2D или наследници на този тип.

Също така имаш и израза List<? super Vertex2D>, който значи - направи List в който можеш да слагаш обекти от тип Vertex2D или негови родители. В случаят основният родител е Object.

0
Filkolev avatar Filkolev 4482 Точки

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

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