Реализация интерфейсов
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 35 из 87.
Чтобы использовать интерфейс, класс должен реализовать его с помощью ключевого слова implements. Затем класс предоставляет конкретные реализации для всех методов, объявленных в интерфейсе:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}Если класс реализует интерфейс, но не предоставляет реализации для всех его методов, компилятор выдаст ошибку. Аннотация @Override является необязательной, но рекомендуется, так как она помогает обнаруживать ошибки.
Так же, как и в случае с абстрактными классами, вы можете использовать интерфейс в качестве ссылочного типа. Это обеспечивает полиморфизм, при котором различные классы, реализующие один и тот же интерфейс, могут обрабатываться единообразно:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Рисование круга с радиусом 5.0
shape2.draw(); // Рисование прямоугольника 4.0 x 3.0Это мощный инструмент, потому что код, работающий со ссылками Drawable, не должен знать конкретный тип класса. Ему важно только то, что объект можно отрисовать.
В следующем уроке вы увидите, как один класс может реализовывать несколько интерфейсов одновременно.
Задание
ЛегкоДавайте создадим систему динамиков, которая демонстрирует, как классы реализуют интерфейсы. Вы создадите интерфейс, определяющий, что может делать любой динамик, а затем создадите два разных типа динамиков, каждый из которых реализует этот контракт по-своему.
Вы организуете свой код в четырех файлах:
Speaker.java: Определите интерфейс с именемSpeaker, который объявляет, что должен уметь делать любой динамик. Каждый динамик должен иметь методspeak(), который возвращает String — это контракт, который должны выполнять все реализующие классы.Human.java: Создайте класс, реализующий интерфейсSpeaker. У Human есть полеname(String). Включите конструктор для инициализации имени и реализуйте методspeak(), чтобы он возвращал:[name] says: Hello everyone!Robot.java: Создайте еще один класс, реализующий интерфейсSpeaker. У Robot есть полеmodel(String). Включите конструктор для инициализации модели и реализуйте методspeak(), чтобы он возвращал:Robot [model] says: Beep boop!Main.java: Объедините все вместе, используя полиморфизм на основе интерфейсов. Вы получите два входных значения: имя человека и модель робота. Создайте Human и Robot, затем сохраните их в массиве ссылокSpeaker. Пройдите циклом по массиву и выведите результат вызоваspeak()для каждого динамика.
Вы получите два входных значения: имя человека (String) и модель робота (String).
Ваш вывод должен содержать две строки — по одной для каждого динамика. Обратите внимание, как и Human, и Robot могут обрабатываться единообразно через интерфейс Speaker, даже если они «говорят» совершенно по-разному!
Шпаргалка
Класс использует ключевое слово implements для реализации интерфейса и должен предоставить конкретные реализации для всех методов, объявленных в интерфейсе:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}Аннотация @Override является необязательной, но рекомендуется, так как она помогает обнаруживать ошибки.
Интерфейсы могут использоваться в качестве ссылочных типов, обеспечивая полиморфизм, при котором различные классы, реализующие один и тот же интерфейс, могут обрабатываться единообразно:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Отрисовка круга с радиусом 5.0
shape2.draw(); // Отрисовка прямоугольника 4.0 x 3.0Попробуйте сами
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Чтение входных данных
String humanName = scanner.nextLine();
String robotModel = scanner.nextLine();
// TODO: Создайте объект Human с заданным именем
// TODO: Создайте объект Robot с заданной моделью
// TODO: Создайте массив ссылок Speaker, содержащий оба объекта
// TODO: Пройдите циклом по массиву и выведите результат speak() для каждого speaker
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»