Разница между абстрактным классом и интерфесом

Какая разница у абстрактного класса и интерфейса в Java?

Просто я понимаю так, что абстрактный класс обязывает иметь какой-либо метод, когда мы наследуем его и интерфейс получается так же?


Ответы (1 шт):

Автор решения: Faraday

Интерфейс обязывает наследуемые классы реализовать указанные методы, а абстрактные классы, и в общем наследование, описывает иерархию объектов. Методы класса описывают поведение объекта.

Класс может наследоваться только от одного родительского класса, и может реализовать (интерфейсы реализуются, а не наследуются) неограниченное количество интерфейсов.

К примеру, у нас есть несколько интерфейсов:

public interface Flyable
{
    public void fly();
}

public interface Runnable
{
    public void run();
}

А так же реализуемые классы:

public class Duck implements Flyable, Runnable
{
    public void fly() { ... }
    public void run() { ... }
}

public class Bird implements Flyable
{
    public void fly() { ... }
}

public class Cat implements Runnable
{
    public void run() { ... }
}

Как вы видите, интерфейс обязывает класс реализовать какое-то поведение. Т.е., вы с помощью интерфейсов вы можете определять поведение ваших классов и перечисление функционала, который этот класс может делать.

Для классов можно рассмотреть структур фигур. У нас есть абстрактный класс, который описывает какую-то фигуру:

public abstract class Shape
{
    protected String color;

    public Shape(String color) {
        this.color = color;
    }

    public abstract double getArea();
    public abstract double getPerimeter();

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

Это какая-то абстрактная фигура, которая уже описывает некий базовый функционал. Почему этот класс абстрактный? Потому что само понятие фигуры это абстрактное понятие, которое описывает в общем какое-то поведение и его обчисляемые параметры, по типу площади или периметра. При описании всей иерархии фигур, мы реализуем абстрактное поведение под конкретные нужды в каждом из классов:

public class Circle extends Shape
{
    private double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }

}

public class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }

    @Override
    public double getArea() {
        return width * height;
    }

    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }
}

Как вы можете заметить, мы переопределяем базовое поведение для каждой из фигур определяя уникальное поведение каждого из классов. Таком образом мы можем получить иерархию объектов с чёткой логикой зависимостей.

Как заключение, вкратце, интерфейс определяет поведение класса, который тот должен реализовать. Класс может реализовать множество интерфейсов. Абстрактные классы используются для описания некой иерархии объектов, а так же могут иметь некоторые поля, методы и конструкторы. Обычно абстрактные классы представляют собой некую абстрактную сущность, объект которой нельзя создать.

→ Ссылка