Как наследование может быть опасным?
Давайте возьмем пример
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 несовместимым. Так что такая зависимость может подниматься до любого уровня, и это может быть опасно. Каждый раз, когда суперкласс может не иметь полной видимости для кода внутри всех его подклассов, и подкласс может постоянно замечать, что происходит в suerclass все время. Поэтому мы должны избегать этой сильной и ненужной связи.
Как композиция решает эту проблему?
Давайте посмотрим, пересматривая тот же пример
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;
}
В классе Test с использованием r reference Я могу вызывать методы класса X, а также класс Y. Эта гибкость никогда не существовала в наследовании
3) Еще одно большое преимущество: Unit testing
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();
}
}
}
Полезно знать:
. Поэтому сделайте его привычкой всегда предпочитать состав над наследованием по разным причинам.