Ограничение нескольких классов в Java - PullRequest
1 голос
/ 16 июня 2019

Я работаю над заданием, и требуется, чтобы я создал две общие коллекции (называемые ComputerOrder и PartyTrayOrder) нескольких классов: ComputerPart, Peripheral и Service, а также и Cheese, Fruit и Service соответственно.Все эти классы (ComputerPart, Fruit, Service и т. Д.) Расширяют один класс под названием Product.

Проблема, с которой я столкнулся, заключается в том, что в Java невозможно связать более одного класса, поскольку вы можете связать только несколько интерфейсов, и мне не разрешено изменять существующую структуру классов.

Я прочитал и увидел, что я предложил создать и интерфейс, который "кодирует" все соответствующие классы, но я не вижу, как это возможно без ComputerPart, Peripheral и т. Д. ТАКЖЕ интерфейсами, а затем с использованиемрасширить ключевое слово.Я также видел, что я предложил создать абстрактные классы под названием ComputerProduct и PartyTrayProduct, но я не вижу, как это каким-либо образом ограничит типы.

Мне не разрешено публиковать изображения, но вот диаграмма классов, включая некоторые несвязанные объекты присваивания

Вот мой текущий код для ComputerOrder, хотя он только ограничивает продукт родительского класса, то есть на самом деле это не так, как указывает присваивание.

public class ComputerOrder<T extends Product> extends GenericOrder<T> {
    public ComputerOrder() {
        super();
    }
}

Вот спецификации назначения:

  1. Разработайте и внедрите универсальный контейнер GenericOrder, который действует как коллекция произвольного числа объектов в Products.java.Разработайте механизм, который дает каждому экземпляру контейнера уникальный идентификатор.Вы должны использовать универсальные функции Java.

  2. Разработка и реализация подкласса GenericOrder с именем ComputerOrder, который принимает произвольное количество различных классов объектов ComputerPart, периферийных объектов и объектов Service.Реализуйте столько методов, сколько необходимо.

  3. Разработайте и реализуйте подкласс GenericOrder с именем PartyTrayOrder, который принимает произвольное число различных классов объектов Cheese, объектов Fruit и Service.Реализуйте столько методов, сколько необходимо.(...)

Ответы [ 2 ]

1 голос
/ 17 июня 2019

Вот единственное решение, которое я придумал, которое следует за присваиванием букве и все еще имеет некоторый смысл (хотя я думаю, что это не «хорошее» решение - см. Примечания ниже) ): ComputerOrder и PartyTrayOrder могут предлагать методы, которые только принимают специализированные типы Product:

abstract class Product {}
class ComputerPart extends Product {}
class Peripheral extends Product { }
class Cheese extends Product {} 
class Fruit extends Product {}
class Service extends Product {} 

abstract class GenericOrder<T extends Product> {
    protected final void addImpl(T t) {
    }
}

class ComputerOrder extends GenericOrder<Product> {
    void add(ComputerPart t) {
        addImpl(t);
    }
    void add(Peripheral t) {
        addImpl(t);
    }
    void add(Service t) {
        addImpl(t);
    }
}

class PartyTrayOrder  extends GenericOrder<Product> {
    void add(Cheese t) {
        addImpl(t);
    }
    void add(Fruit t) {
        addImpl(t);
    }
    void add(Service t) {
        addImpl(t);
    }
}

Таким образом, реализации заказа могут точно принимать правильные типы:

public class ProductExample {

    public static void main(String[] args) {
        ComputerOrder c = new ComputerOrder();
        c.add(new ComputerPart());
        c.add(new Peripheral());
        //c.add(new Cheese()); // Not allowed
        //c.add(new Fruit()); // Not allowed
        c.add(new Service());

        PartyTrayOrder p = new PartyTrayOrder();
        //p.add(new ComputerPart());  // Not allowed
        //p.add(new Peripheral());  // Not allowed
        p.add(new Cheese());
        p.add(new Fruit());
        p.add(new Service());

    }
}

Я предполагаю, что это намеченное решение, потому что назначение содержит широкий намек:

Реализуйте столько методов, сколько необходимо.

Так что, скорее всего, целью является , а не , чтобы реализовать один метод, магически ограниченный для нескольких классов. Вместо этого необходимо добавить один метод для каждой категории.


В сторону: я чувствую, что этот дизайн можно улучшить. Представьте, что вам нужно создать классы CarOrder, FahsionOrder и т. Д. Для новых типов заказов. Или представьте, что PartyTrayOrder нужно будет расширить, чтобы также обрабатывать классы, такие как Meat или Dip или Salad: в итоге вы получите десятки классов с десятками специализированных методов.

Этого можно избежать, введя специальный «тип продукта», который точно соответствует типам, которые приемлемы для определенного «типа заказа». Поэтому я думаю, что (Product должен быть интерфейс для начала, и) должны быть интерфейсы, такие как ComputerProduct и PartyTrayProduct, как в

interface Product {}

interface ComputerProduct extends Product {}
class ComputerPart implements ComputerProduct  {}
class Peripheral implements ComputerProduct  {}

interface PartyTrayProduct extends Product {}
class Cheese implements PartyTrayProduct{} 
class Fruit implements PartyTrayProduct{}

class Service implements Product {} 
class DeliveryService implements PartyTrayProduct{} 
class AssemblyService implements ComputerProduct  {}

Таким образом, требуемые границы для конкретных ComputerOrder и PartyTrayOrder уже смоделированы с помощью иерархии классов. Преимущество: Вам больше не нужны классы ComputerOrder и PartyTrayOrder! Тогда GenericOrder может быть неабстрактным, и для создания определенных типов заказов вы просто правильно использовать привязку общего типа.

Вот полный пример, где я только что добавил Salad как новый PartyTrayProduct и CarPart как новый тип продукта, без необходимости расширять или изменять какие-либо "классы инфраструктуры" :

interface Product {}

interface ComputerProduct extends Product {}
class ComputerPart implements ComputerProduct  {}
class Peripheral implements ComputerProduct  {}

interface PartyTrayProduct extends Product {}
class Cheese implements PartyTrayProduct{} 
class Fruit implements PartyTrayProduct{}

class Service implements Product {} 
class DeliveryService implements PartyTrayProduct{} 
class AssemblyService implements ComputerProduct  {}

class Salad implements PartyTrayProduct{} // A new PartyTrayProduct

// Entirely new product type:
interface CarProduct extends Product {}
class CarPart implements CarProduct  {}
class CarInterior implements CarProduct  {}

class GenericOrder<T extends Product> {
    public void add(T t) { }
}

public class ProductExample2 {
    public static void main(String[] args) {

        GenericOrder<ComputerProduct> c = new GenericOrder<ComputerProduct>();
        c.add(new ComputerPart());
        c.add(new Peripheral());
        //c.add(new Cheese()); // Not allowed
        //c.add(new Fruit()); // Not allowed
        c.add(new AssemblyService());

        GenericOrder<PartyTrayProduct> p = new GenericOrder<PartyTrayProduct>();
        //p.add(new ComputerPart());  // Not allowed
        //p.add(new Peripheral());  // Not allowed
        p.add(new Cheese());
        p.add(new Fruit());
        p.add(new Salad()); // Just add it...
        p.add(new DeliveryService());

        // Easy to extend:
        GenericOrder<CarProduct> e = new GenericOrder<CarProduct>();
        e.add(new CarPart());
        e.add(new CarInterior());
    }
}
0 голосов
/ 16 июня 2019

Эта диаграмма показывает вам, как иерархия классов выглядит одинаково.Каждая жирная стрела является расширением класса.Когда стрелка указывает от A к B, это означает, что A расширяет B. Вы просто должны закрыть это в Java-код.

Когда A расширяет B, а B расширяет C, A - это C. Я не вижу необходимости в множественномБазовое наследование здесь.

...