Являются ли композиция и наследование одинаковыми?
Они не совпадают.
Композиция : позволяет группе объектов обрабатываться так же, как один экземпляр объекта. Цель композита состоит в том, чтобы «компоновать» объекты в древовидных структурах представлять целые иерархии
Inheritance : класс наследует поля и методы из все его суперклассы, прямые или косвенные. Подкласс может переопределять методы, которые он наследует, или он может скрыть поля или методы, которые он наследует.
Если я хочу реализовать шаблон композиции, как я могу это сделать на Java?
Статья в Википедии достаточно хороша для реализации составного шаблона в java.
Ключевые участники:
Компонент:
- Является абстракцией для всех компонентов, включая составные
- Объявляет интерфейс для объектов в композиция
Лист:
- Представляет листовые объекты в композиции
- Реализует все методы Component
Композит:
- Представляет составной компонент (компонент с дочерними элементами)
- Реализует методы манипулирования детьми
- Реализует все методы Component, обычно делегируя их своим детям
Пример кода для понимания Composite patter n:
import java.util.List; import java.util.ArrayList; interface Part{ public double getPrice(); public String getName(); } class Engine implements Part{ String name; double price; public Engine(String name,double price){ this.name = name; this.price = price; } public double getPrice(){ return price; } public String getName(){ return name; } } class Trunk implements Part{ String name; double price; public Trunk(String name,double price){ this.name = name; this.price = price; } public double getPrice(){ return price; } public String getName(){ return name; } } class Body implements Part{ String name; double price; public Body(String name,double price){ this.name = name; this.price = price; } public double getPrice(){ return price; } public String getName(){ return name; } } class Car implements Part{ List
parts; String name; public Car(String name){ this.name = name; parts = new ArrayList (); } public void addPart(Part part){ parts.add(part); } public String getName(){ return name; } public String getPartNames(){ StringBuilder sb = new StringBuilder(); for ( Part part: parts){ sb.append(part.getName()).append(" "); } return sb.toString(); } public double getPrice(){ double price = 0; for ( Part part: parts){ price += part.getPrice(); } return price; } } public class CompositeDemo{ public static void main(String args[]){ Part engine = new Engine("DiselEngine",15000); Part trunk = new Trunk("Trunk",10000); Part body = new Body("Body",12000); Car car = new Car("Innova"); car.addPart(engine); car.addPart(trunk); car.addPart(body); double price = car.getPrice(); System.out.println("Car name:"+car.getName()); System.out.println("Car parts:"+car.getPartNames()); System.out.println("Car price:"+car.getPrice()); } } выход:
Car name:Innova Car parts:DiselEngine Trunk Body Car price:37000.0
Объяснение:
- Часть - это лист
- Автомобиль содержит много частей
- В автомобиль добавлены запчасти автомобиля
- Цена Автомобиль = сумма (Цена каждой партии)
См. ниже вопрос о преимуществах и недостатках композиции и наследования.
Предположим, у нас есть 2 таблицы, имеющие следующие значения:
INSERT INTO `products` (`product_id`)
VALUES (1),(2),(3),(4),(1),(3),(1),(2),(5)
;
INSERT INTO `other_products` (`product_id`)
VALUES (2),(4)
;
Затем этот запрос дает вам счетчик каждого id 1, 3 и 5 (не существует в other_products
)
SELECT `p`.`product_id`, COUNT(`p`.`product_id`) `count`
FROM `products` `p`
LEFT JOIN `other_products` `o`
USING (`product_id`)
WHERE `o`.`product_id` IS NULL
GROUP BY `p`.`product_id`
;
, в то время как этот дает вам общие идентификаторы, которых нет в другой таблице
SELECT count(DISTINCT `p`.`product_id`)
FROM `products` `p`
LEFT JOIN `other_products` `o`
USING (`product_id`)
WHERE `o`.`product_id` IS NULL
;
См. Live Demo
Проблема в том, что ваш подзапрос всегда возвращает значение (иногда возвращает 0), поэтому, когда вы НЕ СУЩЕСТВУЕТЕ (), это всегда ЛОЖЬ, потому что вы всегда получаете ответ. Вы должны изменить NOT EXISTS на 0>, как это
SELECT COUNT(DISTINCT product_id)
FROM products p1
WHERE 0>
(SELECT COUNT(DISTINCT product_id)
FROM products p2
WHERE p2.product_id IN (12,13,14,15,16) AND p1.product_id = p2.product_id)
Если список продуктов взят из приложения, и вы также знаете длину списка (в данном случае 5), вы можете найти количество несуществующих продуктов в таблице, например:
[110 ]Вывод
non_existent_products
2
Если вы не знаете длину списка, вы можете выяснить это, например,
LENGTH('(12, 13, 14, 15, 16)') - LENGTH(REPLACE('(12, 13, 14, 15, 16)', ',', '')) + 1
Обновление
Если другие значения product_id
получены из другого запроса (например, SELECT product_id FROM othertable
]) вы можете найти количество продуктов в этом результате, которых нет в таблице products
, используя LEFT JOIN
результатов этого запроса с таблицей продуктов и взяв разницу в COUNT
с product_id
из два. Примерно так:
SELECT COUNT(DISTINCT q.product_id) - COUNT(DISTINCT p.product_id) AS non_existent_products
FROM (SELECT product_id FROM products2) q
LEFT JOIN products p ON p.product_id = q.product_id
вы можете использовать что-то вроде этого
select count(A.product_id) from (select distinct product_id from product where product_id not in (1,2)) AS A;
здесь вы выбираете отличный product_id из таблицы product, где id продукта не равны 1 и 2, а затем создаете псевдоним для результата как A.
A действует как временная таблица, поэтому вам нужно использовать A.product_id для выбора.
Извините за плохой английский, но я надеюсь, что он отвечает требованию вопроса.