Полиморфизм, абстрактные классы
В данной статье рассмотрим на примере явление полиморфизма, понятие абстрактного класса и интерфейса
Кратко суть полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций». Полиморфизм реализуется с помощью наследования классов. Класс-родитель содержит методы, которые предназначены для наследования.
Реализацию эти методы получают в классе-потомке, поэтому возможно для разных классов-потомков получить разную реализацию метода.
Например мы хотим смоделировать поведение разных животных — кошка, собака, лягушка. Каждый класс является потомком класса Животные, содержащий метод Голос. Каждый производный класс реализует метод Голос. При вызове этого метода в каждом производном классе, реализация этого метода для каждого типа животных будет разная — кошка будет мяукать, собака лаять, а лягушка квакать.
Конкретная реализация метода определена в классе-потомке, поэтому каждое животное по-своему реагирует на вызов метода.
Для того, чтобы увидеть этот механизм в действии, создадим новый родительский класс Animal, реализующий метод getVoice():
package java1; public class Animal { public String getVoice(){ return "AA-AA-AA"; // Вот так у нас реализован этот метод в базовом классе } }
Далее напишем несколько дочерних классов, наследующих этот класс и по-разному реализующих метод getVoice(). Первый класс — Cats, коты мяукают.
package java1; public class Cats extends Animal{ public String getVoice(){ return "Мяу"; // Дочерний класс реализует метод иначе. } }
Второй класс — Dogs, собаки лают.
package java1; public class Dogs extends Animal{ public String getVoice(){ return "Гав"; // Реализация метода для класса Dogs. } }
Далее напишем класс для запуска теста
package java1; public class Test { public static void main(String[] args){ Animal animal = new Cats(); System.out.println("Привет кот, голос: " + animal.getVoice()); animal = new Dogs(); System.out.println("Привет собака, голос: " + animal.getVoice()); animal = new Animal(); System.out.println("Привет кто-то, голос: " + animal.getVoice()); } }
Здесь мы увидим, что объект animal имеет тип Animal, соответствующий родительскому классу. Создаем экземпляры классов, а затем вызов метода ничем не отличается для разных «животных». Это и есть реализация полиморфизма.
Результат выполнения программы
Привет кот, голос: Мяу Привет собака, голос: Гав Привет кто-то, голос: AA-AA-AA
В родительском классе не обязательно определять реализацию того или иного метода. В Java существует возможность вообще не определять реализацию методов класса. Такие методы становятся абстрактными, а сам класс — абстрактным, от абстрактного класса нельзя создать объект, абстрактные методы предназначены только для наследования и не имеют конкретной реализации. От абстрактного класса можно создать дочерний класс, в нем необходимо прописать реализацию абстрактных методов, в противном случае дочерний класс тоже будет абстрактным. Чтобы продемонстрировать все это, перепишем класс Animal, сделаем его абстрактным:
package java1; public abstract class Animal { public abstract String getVoice(); }
В консоли увидим:
Привет кот, голос: Мяу Привет собака, голос: Гав
А как же быть, если мы хотим одни методы реализовать, а другие оставить абстрактными? Абстрактный класс предоставляет нам такую возможность. Но вот если мы хотим все методы сделать абстрактными, для этого мы можем использовать интерфейс — Java Interface. Интерфейс не содержит реализованных методов, в интерфейсе есть только поля и абстрактные методы. Перепишем класс Animal, сделаем его интерфейсом.
package java1; public interface Animal { public String getVoice(); }
В таком случае классы Dogs и Cats претворяют (implements) интерфейс Animal.
public class Cats implements Animal{ public String getVoice(){ return "Мяу"; // Дочерний класс реализует логику иначе. } } public class Dogs implements Animal{ public String getVoice(){ return "Гав"; // Реализация метода для класса Dogs. } }
В итоге, с явлением полиморфизма сталкиваемся, если при создании объекта мы используем тип базового класса или интерфейса, и для каждого объекта прописываем свой вариант реализации метода.