Отношения наследования (IS-A) и композиции (HAS-A)
Описание
Одним из преимуществ объектно-ориентированного языка программирования является повторное использование кода. Есть два способа повторного использования кода: реализация наследования (взаимосвязь IS-A) или композиция объектов (взаимосвязь HAS-A). Хотя компилятор и виртуальная машина Java (JVM) сделают для вас большую работу, когда вы используете наследование, вы также можете получить функциональность наследования, когда вы используете композицию.
IS-A Отношения:
В объектно-ориентированном программировании концепция IS-A полностью основана на наследовании, которое может быть двух типов: наследование класса или наследование интерфейса. Это все равно, что сказать «А это вещь типа Б». Например, яблоко - это фрукт, автомобиль - это транспортное средство и т. Д. Наследование является однонаправленным. Например, Дом - это Здание. Но строительство это не дом.
Важно отметить, что вы можете легко определить отношения IS-A. Везде, где вы видите ключевое слово extends или реализует ключевое слово в объявлении класса, говорят, что этот класс имеет отношение IS-A.
HAS-A Отношения:
Композиция (HAS-A) просто означает использование переменных экземпляра, которые являются ссылками на другие объекты. Например, у Марути есть Двигатель, или у Дома есть Ванная.
Давайте разберемся в этих понятиях на примере класса автомобилей.
package relationships;
class Car {
// Methods implementation and class/Instance members
private String color;
private int maxSpeed;
public void carInfo(){
System.out.println("Car Color="+color + " Max Speed=" + maxSpeed);
}
public void setColor(String color) {
this.color = color;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
Как показано выше, у класса Car есть пара переменных экземпляра и несколько методов. Maruti - это особый тип автомобилей, который расширяет класс автомобилей и означает Maruti IS-A Car.
class Maruti extends Car{
//Maruti extends Car and thus inherits all methods from Car (except final and static)
//Maruti can also define all its specific functionality
public void MarutiStartDemo(){
Engine MarutiEngine = new Engine();
MarutiEngine.start();
}
}
Класс Maruti использует метод start () объекта Engine с помощью композиции. Можно сказать, что у Марути класс HAS-A Engine.
package relationships;
public class Engine {
public void start(){
System.out.println("Engine Started:");
}
public void stop(){
System.out.println("Engine Stopped:");
}
}
Класс RelationsDemo создает объект класса Maruti и инициализирует его. Хотя класс Maruti не имеет методов setColor (), setMaxSpeed () и carInfo (), тем не менее мы можем использовать его из-за связи IS-A класса Maruti с классом Car.
package relationships;
public class RelationsDemo {
public static void main(String[] args) {
Maruti myMaruti = new Maruti();
myMaruti.setColor("RED");
myMaruti.setMaxSpeed(180);
myMaruti.carInfo();
myMaruti.MarutiStartDemo();
}
}
Если мы запустим класс RelationsDemo, мы увидим вывод, как показано ниже.
Сравнение состава и наследования
- Легче изменить класс, реализующий композицию, чем наследование. Смена суперкласса влияет на иерархию наследования на подклассы.
- Вы не можете добавить в подкласс метод с той же сигнатурой, но с другим типом возврата, чем метод, унаследованный от суперкласса. Композиция, с другой стороны, позволяет изменять интерфейс интерфейсного класса, не затрагивая его.
- Композиция - это динамическая привязка (привязка во время выполнения), а наследование - статическая привязка (привязка во время компиляции)
- Легче добавить новые подклассы (наследование), чем добавить новые внешние классы (состав), потому что наследование идет с полиморфизмом. Если у вас есть немного кода, который опирается только на интерфейс суперкласса, этот код может работать с новым подклассом без изменений. Это не относится к композиции, если вы не используете композицию с интерфейсами. Совместное использование композиции и интерфейсов создает очень мощный инструмент проектирования.
- Как с составом, так и с наследованием, легко изменить реализацию (а не интерфейс) любого класса. Волновой эффект изменений реализации остается внутри того же класса.
- Не используйте наследование только для повторного использования кода. Если все, что вам действительно нужно, - это повторное использование кода, а отношения между ними не существует, используйте композицию.
- Не используйте наследование только для того, чтобы достичь полиморфизма. Если все, что вам действительно нужно, это полиморфизм, но нет естественных отношений, используйте композицию с интерфейсами.
Резюме
- Отношение IS-A, основанное на наследовании, которое может быть двух типов: наследование класса или наследование интерфейса.
- Имеет отношение - это композиционные отношения, которые являются продуктивным способом повторного использования кода.
Предыдущая: Пакеты Java
Далее: Массивы - 2D-массив и многомерный массив
Новый контент: Composer: менеджер зависимостей для PHP , R программирования