Как реализуется принцип открытости/закрытости в случае «ветвления» расширений в Java? Есть сущность, которую нужно расширять. Исходя из всех способов расширения, которые указываются в OCP, основной — наследование. Если эту сущность расширяют только в одном направлении, то всё нормально. Но если эту сущность нужно расширять в разных направлениях, как быть? В Java нет множественного наследования. Пример: Есть класс — Человек. Через некоторое время, этот класс захотят расширить по OCP — унаследуются, и сделают класс Бармен. Но если потом класс Человек захотят расширить и в другом направлении? Например — класс Космонавт, также унаследованный от класса Человек. При этом, если нужно, чтобы Человек являлся одновременно и Космонавтом, и Барменом, это не получится из-за того, что Бармен и Космонавт уже будут требовать отдельные экземпляры (instances), что соответствует двум разным людям.
Один из способов решения этой проблемы в Java — использование интерфейсов. Вы можете создать интерфейсы, например, "Работник" и "Космонавт", которые будут имплементироваться классом "Человек". При этом, классы "Бармен" и "Космонавт" могут реализовывать соответствующие интерфейсы. Таким образом, вы можете добавить новые функциональности к классу "Человек" без изменения его основной структуры.
Пример:
interface Работник { public void работать(); } interface Космонавт { public void летать(); } class Человек implements Работник, Космонавт { @Override public void работать() { System.out.println("Человек работает"); } @Override public void летать() { System.out.println("Человек летит в космос"); } } class Бармен implements Работник { @Override public void работать() { System.out.println("Бармен работает"); } } class КосмонавтКосмонавт implements Космонавт { @Override public void летать() { System.out.println("Космонавт летит в космос"); } } public class Main { public static void main(String[] args) { Человек chelovek = new Человек(); chelovek.работать(); chelovek.летать(); Бармен barman = new Бармен(); barman.работать(); Космонавт kosmonavt = new Космонавт(); kosmonavt.летать(); } }
Таким образом, вы можете использовать интерфейсы для гибкого расширения класса "Человек" в разных направлениях, не нарушая принцип открытости/закрытости.
Один из способов решения этой проблемы в Java — использование интерфейсов. Вы можете создать интерфейсы, например, "Работник" и "Космонавт", которые будут имплементироваться классом "Человек". При этом, классы "Бармен" и "Космонавт" могут реализовывать соответствующие интерфейсы. Таким образом, вы можете добавить новые функциональности к классу "Человек" без изменения его основной структуры.
Пример:
interface Работник {public void работать();
}
interface Космонавт {
public void летать();
}
class Человек implements Работник, Космонавт {
@Override
public void работать() {
System.out.println("Человек работает");
}
@Override
public void летать() {
System.out.println("Человек летит в космос");
}
}
class Бармен implements Работник {
@Override
public void работать() {
System.out.println("Бармен работает");
}
}
class КосмонавтКосмонавт implements Космонавт {
@Override
public void летать() {
System.out.println("Космонавт летит в космос");
}
}
public class Main {
public static void main(String[] args) {
Человек chelovek = new Человек();
chelovek.работать();
chelovek.летать();
Бармен barman = new Бармен();
barman.работать();
Космонавт kosmonavt = new Космонавт();
kosmonavt.летать();
}
}
Таким образом, вы можете использовать интерфейсы для гибкого расширения класса "Человек" в разных направлениях, не нарушая принцип открытости/закрытости.