10. Java Интерфейсы | Библиофил — частный блог
Get Adobe Flash player

Чтобы задействовать полиморфизм, нужны интерфейсы (нет, не те, что предназначены для пользователя). Пора оставить позади обычное наследование и выйти на новый уровень гибкости и масштабируемости. Его может обеспечить только архитектура, основанная на интерфейсах. Самые замечательные возможности Java существуют лишь благодаря интерфейсам, поэтому, даже если вы не используете их в работе, все равно придется столкнуться с ними. Но мы уверены, что вы захотите использовать их. Вы удивитесь, как могли жить без них раньше.
Что такое интерфейс? Это на 100 % абстрактный класс. Что такое абстрактный класс? Это класс, для которого нельзя создать экземпляр. Зачем это нужно? Вы скоро увидите.
Если вы думаете об окончании предыдущей главы, где мы использовали полиморфические аргументы так, чтобы единственный метод Vet мог принимать дочерние классы Animal всех типов, то это было только начало. Интерфейсы — это «поли» в слове «полиморфизм», «аб» в слове «абстрактный» и «кофеин» в Java.
Это способ, предотвращающий создание экземпляров класса, а точнее останавливающий любого, кто захочет задать new для этого типа. Нужно лишь отметить класс словом abstract, и компилятор остановит процесс создания экземпляра этого типа в любой части кода.
Абстрактный класс практически* не используется, у него нет значения, нет цели в жизни, если только он не расширенный. Элементы абстрактного класса, делающие работу при выполнении программы, являются экземплярами его дочернего класса. *Здесь есть исключение абстрактный класс может содержать статические элементы.
Если класс не абстрактный, то он называется конкретным.
Кроме классов вы можете делать абстрактными и методы. Если класс абстрактный, значит, его необходимо расширить; если же абстрактным является метод, он должен быть переопределен. Вы можете решить, что поведение абстрактного класса (полностью или частично) не имеет смысла, если оно не реализовано более специфическими подклассами.
Другими словами, не получится представить реализацию общего метода, которая может оказаться полезной для дочерних классов. Как бы выглядел общий метод eat()? У абстрактных методов нет тела!
Поскольку вы уже поняли, что в абстрактном методе нет кода, который имел бы смысл, то не станете добавлять тело метода. public abstract void eat ();
Поэтому нет и фигурных скобок — просто закрываем объявление точкой с запятой. Если вы объявляете абстрактный метод, то должны сделать абстрактным и его класс- Нельзя иметь абстрактный метод в неабстрактном классе. Даже помещая один абстрактный метод в класс, вы обязаны сделать этот класс абстрактным. Однако можно совмещать как абстрактные, так и неабстрактные методы в абстрактном классе.
Абстрактные методы не имеют тела; они существуют только для полиморфизма. Это значит, что первый конкретный класс в дереве наследования должен реализовать все абстрактные методы. Однако вы можете переложить ответственность на кого-то еще, если сами абстрактны. Например, если оба класса Animal и Canine абстрактны и содержат абстрактные методы, то класс Canine не обязан реализовывать методы класса Animal. Но как только мы доберемся до первого конкретного подкласса, например Dog, этот подкласс должен будет реализовать все абстрактные методы из обоих классов Animal и Canine. Однако не забывайте, что абстрактный класс может включать как абстрактные, так и неабстрактные методы, поэтому, например, Canine мог бы реализовать абстрактные методы Animal, чтобы этого не пришлось делать подклассу Dog. Но если Canine не скажет ничего про абстрактные методы Animal, то Dog должен будет реализовать их все. Когда мы говорим: «Вы должны реализовать абстрактный метод», это означает, что вы должны дать методу тело. Иными словами, нужно создать неабстрактный метод в классе с такой же сигнатурой метода (именем и аргументами) и возвращаемым типом, совместимым с объявленным возвращаемым типом абстрактного метода. Что вы поместите в этот метод, зависит от вас. Java волнует только то, что метод находится там, в вашем конкретном дочернем классе.
И помните правило интерфейсов — при реализации интерфейса вы объявляете об этом. Это означает, что вы должны написать способы реализации для каждого метода в интерфейсе.