После продолжительного программирования на C++ переходить на Java бывает болезненно. С одной стороны прославленный сборщик мусора, а с другой огромное множество принципиальных различий в подходах к программированию. Об одном таком отличии я сегодня расскажу подробнее.
Речь пойдет о наследовании в Java. В отличии от C++, где наследование могло быть множественным, здесь это не совсем так. Кроме того, привычный синтаксис через «:» заменился на целых два ключевых слова: extends и implements. Начну с первого.
Ключевое слово extends в Java
Действие ключевого слова в точности совпадает с его переводом, один класс расширяет другой, что является классическим наследованием. Правила видимости полей и методов сохранились: private доступны только в самом классе, protected в самом классе и во всех наследниках, к public методам и полям можно обращаться откуда угодно. Главное отличие от «сишного» наследования в том, что можно расширять только один класс. Я сейчас не буду рассуждать о том, насколько это удобно, скажу только, что со множественным наследованием в C++ постоянно творилась какая-то каша.
Небольшой пример наследования с помощью ключевого слова extends. Напишем класс Door, который будет описывать характеристики двери, мы можем создать объект этого класса и работать с ним, как с «просто дверью». С другой стороны напишем еще два класса: IronDoor и WoodDoor, которые будут расширять класс Door(== наследуются от класса Door), т.е. добавят свои характеристики к базовым.
//Базовый класс "дверь"
public class Door {
//Допустим, что у любой двери есть цена
protected int price;
//Этот метод тоже наследуется
protected void doSomething() {
System.out.println("Door is doing something");
}
//Этот метод доступен исключительно в классе Door
private void onlyForDoor() {
}
}
//Железная дверь
public class IronDoor extends Door {
//Уровень защиты определен только для железных дверей
private int protectionLvl;
IronDoor(int price, int protectionLvl) {
this.price = price;
this.protectionLvl = protectionLvl;
}
}
//Деревянная дверь
public class WoodDoor extends Door {
//Характеристика "порода древесины" доступна только деревянной двери
private String woodType;
WoodDoor(int price, String woodType) {
this.price = price;
this.woodType = woodType;
}
}
Ключевое слово implements в Java
С ключевым словом implements связано чуть больше хитростей. Слово «имплементировать» можно понимать, как «реализовывать», а в тот самый момент, когда возникает слово «реализовывать», где-то недалеко появляются интерфейсы. Так вот конструкция public class Door implements Openable означает, что класс дверь реализует интерфейс «открывающийся». Следовательно класс должен переопределить все методы интерфейса. Главная фишка в том, что можно реализовывать сколь угодно много интерфейсов.
Зачем это нужно? Самый простой пример, который приходит в голову, два интерфейса: Openable и Closeble. В первом метод open, и метод close во втором. Они помогут научить нашу дверь закрываться и открываться.
public interface Openable {
void open();
}
public interface Closeble {
void close();
}
public class Door implements Openable, Closeble {
protected int price;
protected void doSomething() {
System.out.println("Door is doing something");
}
//Реализованные методы
@Override
public void open() {
}
@Override
public void close() {
}
}
В классах-потомках двери(железная и деревянная двери) тоже появятся методы открыть/закрыть, реализованные в классе Door. Но никто нам не запрещает их переопределить.
public class IronDoor extends Door {
private int protectionLvl;
IronDoor(int price, int protectionLvl) {
this.price = price;
this.protectionLvl = protectionLvl;
}
//Переопределяем методы
@Override
public void open() {
System.out.println("The IRON door is opened");
}
@Override
public void close() {
System.out.println("The IRON door is closed");
}
}
Заключение
Итак, главное отличие в том, что extends используется для наследования от класса в прямом смысле этого слова, а implements позволяет «реализовать интерфейс». На первый взгляд это кажется лишним, неудобным и непонятным, но стоит пару раз использовать по назначению и все встает на свои места. На сегодня у меня все, спасибо за внимание!