Объектно-ориентированный дизайн — как вложить один класс в другой класс

Я пришел из мира реляционных баз данных, и мне приходится создавать свою первую объектно-ориентированную программу, и, несмотря на обучение, я просто не могу понять, как делать самые простые вещи.

Я определил класс Product (int id, String productName, double price...) с его методами и атрибутами и класс ProductFamily (String familyName, String costCenter...) с собственными методами и атрибутами.

Как связать/встроить оба класса? Я пытался использовать подклассы с ключевым словом «extends», но это просто наследует методы от одного к другому. Это не позволяет мне создать экземпляр нового объекта продукта в данном семействе продуктов.

Спасибо!!

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
68
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы должны добавить поле в свой класс Product, который является объектом класса ProductFamily. Добавив метод getProductFamily() в свой класс Product, вы можете вернуть семейства продуктов для конкретного продукта.

Спасибо, это имеет смысл, но как создать конструктор для добавления поля, которое, в свою очередь, является классом? общедоступный продукт (int id, String productName, двойная цена...) {}

Hernán Ruiz 09.03.2019 20:01

public Product (int id, String productName, double price, семейство ProductFamily) {} Если вы создаете новый продукт: Product p = new Product(1, "независимо", 1.0, someresource), где "someresource" является объектом существующего Семейство продуктов.

Natha 10.03.2019 12:54

Это может быть так, если предположить, что между классами ProductFamily и Product существует отношение 1 к N:

class ProductFamily{

    private List<Product> products;

    //add all other members and getters and setters
}

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

 class ProductFamily{

    private List<Product> products;

    //add all other members and getters and setters

    public void addProduct(Product newProduct){
        this.products.add(newProduct);
    }
}

Спасибо, это определенно отношение 1 ко многим. Я действительно не знаю, как таким образом добавить новый продукт в ProductFamily, я добавил предложенную вами строку, но... Я полагаю, что на этот вопрос был дан ответ миллион раз, но я не могу найти ответ или где-либо прочитать об этом. Спасибо!!

Hernán Ruiz 09.03.2019 20:24

@HernánRuiz Я отредактировал ответ, чтобы показать вам метод

uneq95 09.03.2019 20:30

Спасибо еще раз! Извините за то, что я такой новичок/идиот, но как мне таким образом создать экземпляр нового продукта в семействе продуктов?

Hernán Ruiz 09.03.2019 21:16

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

uneq95 09.03.2019 21:57

Вы можете расширить только один класс в Java. Вы можете сделать это во многих классах. Если вы хотите расширить несколько классов с одинаковыми именами функций, я бы использовал интерфейсы.

Если вы пришли из мира реляционных баз данных, у вас может быть четкое представление о нескольких взаимосвязанных концепциях, включая реляционные соединения, нормализацию данных, логическую независимость данных, самоописывающие данные, транзакции ACID и управление параллелизмом. Новичку трудно по-настоящему осознать силу и простоту каждой из этих концепций, не зная их всех. Хотите верьте, хотите нет, но специалистам по объектному моделированию нелегко понять каждую из этих концепций, просто сравнивая их с тем, что они уже знают.

То же самое происходит, когда вы впервые начинаете изучать объектное моделирование. Три взаимосвязанных понятия — это наследование, инкапсуляция и полиморфизм. Ни один из них не имеет большого смысла без некоторого понимания двух других. Все они работают вместе, чтобы создать мощную и простую систему.

Не поддавайтесь искушению рассматривать объектную модель как реляционную модель, только без некоторых функций. Это чрезмерное упрощение объектной модели. Правда в том, что каждая из этих парадигм моделирования была огромным шагом вперед в современном искусстве моделирования примерно сорок-пятьдесят лет назад. Каждый из них значительно упрощает размышления о существующих системах или предлагаемых системах, которые еще предстоит построить.

Но они не похожи друг на друга, и ни один из них не был производным от другого.

Если вы собираетесь начать с реляционного мышления, вот с чего начать. Решите, является ли отношение между Product и ProductFamily отношением HAS-A или отношением IS-A. Отношения HAS-A легко моделируются (реляционно) с использованием отдельных таблиц и внешних ключей. Что касается объектов, их лучше всего моделировать как отдельные классы со ссылкой из одного на другой. Отношения IS-A разные. Например, в зоомагазине могут быть кошки, собаки, птицы и змеи, но все они домашние животные. есть некоторые атрибуты или методы, которые относятся только к птицам или кошкам, но есть и другие, которые относятся ко всем им.

Ближайший аналог суперкласса/подкласса в реляционном моделировании находится не в реляционной модели, а в модели расширенных отношений сущностей. Здесь есть понятие, называемое Обобщение/Специализация. Кошка, собака, птица или змея — это специализация домашнего животного. Это отношения IS-A. Если обобщение/специализация имеет для вас смысл в данном случае, то подклассы и наследование сослужат вам хорошую службу. Если нет, то вам лучше не пытаться использовать здесь подклассы.

Здесь, в StackOverflow, есть буквально сотни вопросов, которые задают люди, привыкшие к объектному моделированию и желающие узнать, как реализовать отношения IS-A с таблицами SQL. Последний пример находится рядом с вашим вопросом и называется Расписание присоединения к нескольким столам. Для таких людей есть тег . Им трудно понять, как реляционная модель может что-либо делать без концепции наследования. Ваша проблема в обратном. Как и когда использовать наследование, чтобы сделать жизнь проще, чем в реляционной схеме. И когда не использовать наследование.

Вам нужно решить, являются ли Product и ProductFamily тем случаем, когда полезно наследование. Опять же, если это отношение HAS-A, забудьте о подклассах и наследовании. Если это отношения IS-A, наследование является ключом к простому решению. Чтобы выполнять значимые операции над суперклассом, вам придется либо ограничиться операциями, значимыми для суперкласса, либо научиться создавать полиморфные операции. Этому нужно многому научиться, но в конце пути есть большая ценность.

Другие вопросы по теме