Являются ли композиция и наследование одинаковыми? Если я хочу реализовать шаблон композиции, как я могу это сделать на Java?
Разница между наследованием и композицией
Ответ 1
Они абсолютно разные. Наследование - это отношение "is-a". Композиция - это "has-a".
Вы делаете композицию, имея экземпляр другого класса C как поле своего класса, вместо расширения C. Хорошим примером того, что композиция была бы намного лучше, чем наследование, является java.util.Stack, который в настоящее время расширяет java.util.Vector. Это сейчас считается ошибкой. Вектор "-НЕ-a" стека; вам не разрешается вставлять и удалять элементы произвольно. Это должно было быть композиция.
К сожалению, слишком поздно исправить эту ошибку дизайна, так как изменение иерархии наследования теперь нарушит совместимость с существующим кодом. Вместо Stack использовался состав вместо наследования, он всегда может быть изменен для использования другой структуры данных, не нарушая API.
Я очень рекомендую книгу Джоша Блоха Эффективное Java 2nd Edition
- Пункт 16: Офорт композиции над наследованием
- Пункт 17: Дизайн и документ для наследования или запрет на него
Хороший объектно-ориентированный дизайн - это не либеральное расширение существующих классов. Ваш первый инстинкт должен составлять вместо этого.
См. также:
Ответ 2
Состав означает HAS A 
Наследование означает IS A
 Example: Автомобиль  имеет Двигатель и автомобиль  - это Автомобиль
В программировании это представляется как:
class Engine {} // The Engine class.
class Automobile {} // Automobile class which is parent to Car class.
class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}
Ответ 3
Насколько наследование может быть опасным?
Давайте возьмем пример
public class X{    
   public void do(){    
   }    
}    
Public Class Y extends X{
   public void work(){    
       do();    
   }
}
1) Как ясно из приведенного выше кода, класс Y имеет очень сильную связь с классом X. Если что-то изменится в суперклассе X, Y может резко сломаться. Предположим, что в будущем класс X реализует метод работы с подписью ниже
public int work(){
}
Изменение сделано в классе X, но это сделает класс Y некомпилируемым. Так что такая зависимость может подняться на любой уровень, и это может быть очень опасно. Каждый раз, когда суперкласс может не иметь полной видимости кода внутри всех его подклассов, и подкласс может постоянно замечать, что происходит в суперклассе все время. Поэтому нам нужно избегать этой сильной и ненужной связи.
Как композиция решает эту проблему?
Давайте посмотрим, пересмотрев тот же пример
public class X{
    public void do(){
    }
}
Public Class Y{
    X x = new X();    
    public void work(){    
        x.do();
    }
}
Здесь мы создаем ссылку на класс X в классе Y и вызываем метод класса X, создавая экземпляр класса X. Теперь все, что сильная связь исчезла. Суперкласс и подкласс теперь очень независимы друг от друга. Классы могут свободно вносить изменения, которые были опасны в ситуации наследования.
2) Второе очень хорошее преимущество композиции в том, что оно обеспечивает гибкость вызова метода, например:
class X implements R
{}
class Y implements R
{}
public class Test{    
    R r;    
}
В тестовом классе, используя ссылку r, я могу вызывать методы класса X, а также класса Y. Эта гибкость никогда не была в наследстве
3) Еще одно большое преимущество: модульное тестирование
public class X {
    public void do(){
    }
}
Public Class Y {
    X x = new X();    
    public void work(){    
        x.do();    
    }    
}
В приведенном выше примере, если состояние экземпляра x неизвестно, его можно легко смоделировать, используя некоторые тестовые данные, и все методы можно легко протестировать. Это было невозможно вообще при наследовании, так как вы сильно зависели от суперкласса, чтобы получить состояние экземпляра и выполнить любой метод.
4) Еще одна веская причина, по которой мы должны избегать наследования, заключается в том, что Java не поддерживает множественное наследование.
Давайте рассмотрим пример, чтобы понять это:
Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b = new Deposit();    
        if(b.deposit()){    
            b = new Credit();
            c.credit();    
        }
    }
}
Хорошо знать:
-  состав легко достигается во время выполнения, в то время как наследование обеспечивает его особенности во время компиляции 
-  состав также известен как отношение HAS-A, а наследование также известно как отношение IS-A 
Так что возьмите в привычку всегда предпочитать композицию наследованию по разным причинам.
Ответ 4
Ответ, заданный @Michael Rodrigues, неверен (я извиняюсь, я не могу комментировать напрямую) и может привести к некоторой путанице.
Интерфейсная реализация является формой наследования... при реализации интерфейса вы не только наследуете все константы, что ваш объект будет иметь тип, указанный интерфейсом; он по-прежнему является " is-a" . Если автомобиль реализует Fillable, автомобиль " is-a" Fillable и может использоваться в вашем коде везде, где вы бы использовали Fillable.
Состав принципиально отличается от наследования. Когда вы используете композицию, вы (как и другие ответы) отмечаете связь " has-a" между двумя объектами, в отличие от отношения " is-a" которые вы делаете, когда используете наследование.
Итак, из примеров автомобилей в других вопросах, если бы я хотел сказать, что бензобак " имеет-", я бы использовал композицию следующим образом:
public class Car {
private GasTank myCarsGasTank;
}
Надеюсь, это устранит любые недоразумения.
Ответ 5
 Наследование выявляет отношения IS-A. Композиция выявляет отношения HAS-A. Шаблон стратегии объясняет, что Composition следует использовать в тех случаях, когда существуют семейства алгоритмов, определяющих конкретное поведение. 
 Классическим примером является класс утки, который реализует летное поведение.
public interface Flyable{
 public void fly();
}
public class Duck {
 Flyable fly;
 public Duck(){
  fly = new BackwardFlying();
 }
}
Таким образом, мы можем иметь несколько классов, которые реализуют полет, например:
public class BackwardFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies backward ");
  }
}
public class FastFlying implements Flyable{
  public void fly(){
    Systemout.println("Flies 100 miles/sec");
  }
}
Если бы это было по наследству, у нас было бы два разных класса птиц, которые снова и снова выполняют функцию мухи. Так что наследование и состав совершенно разные.
Ответ 6
Композиция так же звучит - вы создаете объект, вставляя части.
  ИЗМЕНИТЬ, остальная часть этого ответа ошибочно основана на следующей предпосылке. 
Это достигается с помощью интерфейсов. 
Например, используя пример Car выше,
Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel
Итак, с помощью нескольких стандартных теоретических компонентов вы можете создать свой объект. Затем выполните свою работу, чтобы заполнить, как House защищает своих обитателей и как Car защищает своих обитателей.
Наследование похоже на обратное. Вы начинаете с полного (или полуполного) объекта, и вы заменяете или переопределяете различные биты, которые хотите изменить.
Например, MotorVehicle может иметь метод Fuelable и Drive. Вы можете оставить метод Fuel так, как он есть, потому что он заполняет мотоцикл и автомобиль, но вы можете переопределить метод Drive, потому что Motorbike очень сильно отличается от Car.
С наследованием некоторые классы уже полностью реализованы, а в других - методы, которые вы вынуждены переопределять. С композицией ничего не дано вам. (но вы можете реализовать интерфейсы, вызывая методы в других классах, если у вас что-то лежит).
Композиция считается более гибкой, потому что, если у вас есть такой метод, как iUsesFuel, вы можете иметь метод где-то еще (другой класс, другой проект), который просто беспокоится о работе с объектами, которые могут питаться, независимо от того, автомобиль, катер, плита, барбекю и т.д. Интерфейсы гарантируют, что классы, которые говорят, что они реализуют этот интерфейс, действительно имеют методы, которыми обладает этот интерфейс. Например,
iFuelable Interface:
   void AddSomeFuel()
   void UseSomeFuel()
   int  percentageFull()
тогда у вас может быть метод где-то еще
private void FillHerUp(iFuelable : objectToFill) {
   Do while (objectToFill.percentageFull() <= 100)  {
        objectToFill.AddSomeFuel();
   }
Странный пример, но он показывает, что этот метод не заботится о том, что он заполняет, потому что объект реализует iUsesFuel, его можно заполнить. Конец истории.
Если вы использовали Наследование, вам понадобятся разные методы FillHerUp для работы с MotorVehicles и Barbecues, если у вас не есть какой-то довольно странный базовый объект ObjectThatUsesFuel, из которого можно наследовать.
Ответ 7
Являются ли композиция и наследование одинаковыми?
Они не одинаковы.
Состав: он позволяет обрабатывать группу объектов так же, как один экземпляр объекта. Цель композита состоит в том, чтобы "компонировать" объекты в древовидных структурах с представлять иерархии целого целого.
Наследование: класс наследует поля и методы из всех своих суперклассов, будь то прямые или косвенные. Подкласс может переопределять методы, которые он наследует, или может скрывать поля или методы, которые он наследует.
Если я хочу реализовать шаблон композиции, как я могу это сделать на Java?
Wikipedia статья достаточно хороша, чтобы реализовать составной шаблон в java.
Ключевые участники:
Компонент:
- Является абстракцией для всех компонентов, включая составные.
- Объявляет интерфейс для объектов в композиции
лист
- Представляет листовые объекты в композиции
- Реализует все методы компонентов
Composite
- Представляет составной компонент (компонент, имеющий дочерние элементы)
- Реализует методы управления детьми
- Реализует все методы Component, обычно путем делегирования их дочерним элементам
Пример кода для понимания шаблона Композитный:
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<Part> parts;
    String name;
    public Car(String name){
        this.name = name;
        parts = new ArrayList<Part>();
    }
    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
Пояснение:
- Часть - это лист
- Автомобиль содержит много частей
- В автомобиль добавлены различные запчасти автомобиля
- Цена Автомобиль= сумма (Цена каждой Части)
См. ниже вопрос о преимуществах и недостатках композиции и наследования.
Ответ 8
в качестве другого примера рассмотрим класс автомобилей, это будет хорошим использованием композиции, автомобиль будет иметь "двигатель", коробку передач, шины, сиденья и т.д. Он не будет распространять ни один из этих классов.
Ответ 9
В простой агрегации слов означает "Отношения".
Состав - это особый случай агрегации. Более конкретно, ограниченная агрегация называется композицией. Когда объект содержит другой объект, если содержащийся объект не может существовать без существования контейнерного объекта, тогда он называется композицией. Пример: класс содержит учащихся. Студент не может существовать без класса. Существует композиция между классом и учениками.
Зачем использовать агрегацию
Повторное использование кода
При использовании агрегации
Повторное использование кода также наилучшим образом достигается путем агрегирования, когда нет отношения к кораблю
Наследование
Наследование является родительским отношением к наследству от детей. Это отношение
Наследование в java - это механизм, в котором один объект приобретает все свойства и поведение родительского объекта.
Использование наследования в Java 1 Повторное использование кода. 2 Добавить дополнительную функцию в дочернем классе, а также переопределить метод (так что полиморфизм времени выполнения может быть достигнут).
Ответ 10
Наследование между двумя классами, где один класс расширяет другой класс, устанавливает связь " IS A".
Состав на другом конце содержит экземпляр другого класса в вашем классе, который устанавливает связь " имеет A". Состав в java полезен, поскольку он технически облегчает множественное наследование.
Ответ 11
Состав состоит из того, что что-то состоит из отдельных частей и имеет прочные отношения с этими частями. Если основная часть умирает, так и другие, у них не может быть собственной жизни. Грубым примером является человеческое тело. Выньте сердце, и все остальные части отмирают.
Наследование - это то, где вы просто берете то, что уже существует и использует его. Нет сильных отношений. Человек мог наследовать свое отцовское имение, но он может обойтись без него.
Я не знаю Java, поэтому не могу привести пример, но я могу дать объяснение понятий.
Ответ 12
Несмотря на то, что оба наследования и композиции обеспечивают повторное использование кода, основное различие между композицией и наследованием в Java заключается в том, что Composition позволяет повторно использовать код без его расширения, но для Inheritance вы должны расширить класс для повторного использования кода или функциональности. Другое отличие от этого факта заключается в том, что с помощью композиции вы можете повторно использовать код для даже окончательного класса, который не является расширяемым, но Inheritance не может повторно использовать код в таких случаях. Кроме того, используя Composition, вы можете повторно использовать код из многих классов, поскольку они объявлены как только переменная-член, но с Inheritance вы можете повторно использовать форму кода только одного класса, потому что в Java вы можете расширять только один класс, поскольку множественное Наследование не поддерживается в Java, Вы можете сделать это на С++, хотя из-за того, что один класс может расширять несколько классов. BTW, вы всегда должны предпочитать композицию над наследованием в Java, ее не только я, но даже Джошуа Блох предложил в своей книге
Ответ 13
Я думаю, что этот пример ясно объясняет различия между наследованием и композицией.
В этом случае проблема решена с использованием наследования и композиции. Автор обращает внимание на то, что; в наследовании изменение суперкласса может вызвать проблемы в производном классе, которые наследуют его.
Там вы также можете увидеть разницу в представлении, когда используете UML для наследования или композиции.
Ответ 14
Наследование с композицией.
Наследования и состав используются для повторного использования и расширения поведения класса.
Наследование в основном используется в модели программирования алгоритмов семейства, такой как тип отношения IS-A, означает аналогичный вид объекта. Пример.
- Duster - автомобиль
- Сафари - автомобиль
Они относятся к семейству Car.
Композиция представляет собой отношение HAS-A Type.It показывает способность объекта, такого как Duster, имеет Five Gears, Safari имеет четыре Gears и т.д. Всякий раз, когда нам нужно расширить способность существующего класса, используйте композицию. Пример нам нужно добавить еще одну передачу в объект Duster, тогда мы должны создать еще один объект передачи и скомпоновать его объекту duster.
Мы не должны вносить изменения в базовый класс до тех пор, пока все производные классы не будут нуждаться в этих функциях. Для этого сценария мы должны использовать композицию. Так как
класс A Производится классом B
Класс A, полученный классом C
Класс A, полученный классом D.
Когда мы добавляем какие-либо функциональные возможности в класс А, тогда он доступен для всех подклассов, даже если классам C и D не требуются эти функции. Для этого сценария нам необходимо создать отдельный класс для этих функций и составить его для требуемый класс (вот класс B).
Ниже приведен пример:
          // This is a base class
                 public abstract class Car
                    {
                       //Define prototype
                       public abstract void color();
                       public void Gear() {
                           Console.WriteLine("Car has a four Gear");
                       }
                    }
           // Here is the use of inheritence
           // This Desire class have four gears.
          //  But we need to add one more gear that is Neutral gear.
          public class Desire : Car
                   {
                       Neutral obj = null;
                       public Desire()
                       {
     // Here we are incorporating neutral gear(It is the use of composition). 
     // Now this class would have five gear. 
                           obj = new Neutral();
                           obj.NeutralGear();
                       }
                       public override void color()
                       {
                           Console.WriteLine("This is a white color car");
                       }
                   }
             // This Safari class have four gears and it is not required the neutral
             //  gear and hence we don't need to compose here.
                   public class Safari :Car{
                       public Safari()
                       { }
                       public override void color()
                       {
                           Console.WriteLine("This is a red color car");
                       }
                   }
   // This class represents the neutral gear and it would be used as a composition.
   public class Neutral {
                      public void NeutralGear() {
                           Console.WriteLine("This is a Neutral Gear");
                       }
                   }
Ответ 15
Композиция означает создание объекта для класса, который имеет отношение к этому конкретному классу. Предположим, что у Студента есть связь со Счетами;
Наследование - это предыдущий класс с расширенной функцией. Это означает, что этот новый класс - это класс Old с некоторой расширенной функцией. Предположим, что студент - студент, но все ученики - это люди. Так что есть отношения со студентами и людьми. Это Наследование.
Ответ 16
Нет, оба разные. Композиция соответствует отношениям "HAS-A" и наследованию следуют отношения "IS-A". Лучшим примером для композиции был стратегический паттерн.
Ответ 17
Наследование означает повторное использование всей функциональности класса. Здесь мой класс должен использовать все методы суперкласса, и мой класс будет аккуратно связан с суперклассом, и код будет продублирован в обоих классах в случае наследования.
Но мы можем преодолеть все эти проблемы, когда используем композицию для общения с другим классом. Композиция объявляет атрибут другого класса в моем классе, с которым мы хотим поговорить. и какую функциональность мы хотим от этого класса, мы можем получить с помощью этого атрибута.
Ответ 18
композиция
- способ объединить простые объекты или типы данных в более сложные
- Композиционные отношения существуют между двумя классами, если одно (ие) поле (и) классов состоит из другого класса.
- Называется как имеет отношения
наследование
- На первый взгляд, наследование - это повторное использование кода.
- мы можем расширить код, который уже написан управляемым способом.
- Наследование больше, оно поддерживает полиморфизм на уровне языка!
- Информация становится управляемой в иерархическом порядке
- С наследованием новый класс может быть получен из существующих классов как строительный блок
- Новый класс Наследовать свойства и методы из существующего класса
- используя расширяет и реализует ключевые слова
- Существует иерархия классов (Direct/Indirect/Single/Multiple)

