Полиморфизм, абстрактные классы Наука  Наука 

Полиморфизм, абстрактные классы

В данной статье рассмотрим на примере явление полиморфизма, понятие абстрактного класса и интерфейса

Кратко суть полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций». Полиморфизм реализуется с помощью наследования классов. Класс-родитель содержит методы, которые предназначены для наследования.

Реализацию эти методы получают в классе-потомке, поэтому возможно для разных классов-потомков получить разную реализацию метода.

Например мы хотим смоделировать поведение разных животных — кошка, собака, лягушка. Каждый класс является потомком класса Животные, содержащий метод Голос. Каждый производный класс реализует метод Голос. При вызове этого метода в каждом производном классе, реализация этого метода для каждого типа животных будет разная  — кошка будет мяукать, собака лаять, а лягушка квакать.

Конкретная реализация метода определена в классе-потомке, поэтому каждое животное по-своему реагирует на вызов метода.

Для того, чтобы увидеть этот механизм в действии, создадим новый родительский класс 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.
    }
}

В итоге,  с явлением полиморфизма сталкиваемся, если при создании объекта мы используем тип базового класса или интерфейса, и для каждого объекта прописываем свой вариант реализации метода.

Похожие записи