Долго меня мучил вопрос чем же все таки отличаются abstract class и interface в java.
Если посмотреть на определение то abstract class это базовый класс, который не предполагает создания экземпляров. А Interface это описание предполагаемого поведения класса, не упоминая конкретных действий. Другими словами интерфейс предполагает только объявление методов и полей для реализующего данный интерфейс класса.
Пример интерфейса A:
public interface IContent {
public void getUser();
public void getValue();
}
В интерфейсе все поля и методы должны быть публичными (public). В данном примере мы создали интерфейс Content и указали два метода: getUser и getValue.
Теперь нам нужно создать несколько классов, которые реализуют данный интерфейс. Так как просто контента быть не может, а может быть статья, коментарий, файл на скачку ролик, поэтому нам их надо реализовать.
public class Post implements IContent{
@Override
public void getUser()
// тут его реализация
}
@Override
public void getValue()
// тут его реализация
}
}
...
public class Video implements IContent{
@Override
public void getUser()
// тут его реализация
}
@Override
public void getValue()
// тут его реализация
}
}
И так далее. Вполне нормально, но метод getUser() для всех одинаков. Поэтому не самое лучшее решение в каждом классе его реализовывать. Поэтому нам лучше сделать так:
public abstract class AContent {
private String user;
public String getUser(){
return user;
}
public abstract String getValue();
}
public class Post extends extends AContent{
public Post(){
// тут конструктор
}
@Override
public void getValue()
// тут его реализация
}
}
...
public class Video extends AContent{
public Video(){
// тут конструктор
}
@Override
public void getValue()
// тут его реализация
}
}
В абстрактном классе AContent мы полностью реализовали получение user. Метод получения user есть и в видео и в статье. А вот метод получения значения в абстрактном классе не определен, а только объявлен, поэтому их надо переопределить и реализовать в наследниках.
Аспект | abstract class | interface |
Назначение | Как любой базовый класс, представляет ядро поведения для всех наследников. Если в абстрактном классе не реализован ни один метод, имеет смысл превратить его в интерфейс. | Контракт, ничего более. Интерфейсы часто используются (и во основном предназначены для этого) как примеси без реализации при проектировании иерархии классов. |
Реализация по умолчанию | Может быть частично или полностью реализован, предоставлять базовую функциональность. | Не может содержать какой-либо код. |
Модификаторы доступа членов | Члены могут иметь все допустимые модификаторы доступа. | Только public. |
Наследование | Наследование от абстрактного класса реализует отношение "является". | Наследование от интерфейса определяет отношение "реализует". |
Множественное наследование | Класс может наследовать только один класс. | Класс может наследовать несколько интерфейсов. При этом он может и не реализовывать методы интерфейса, т. е. быть абстрактным. Сам интерфейс тоже может наследовать несколько интерфейсов. |
Расширение | При добавлении нового метода в абстрактный класс, мы можешь реализовать его, тем самым не нарушив работу наследующих классов. Если тело метода оставить нереализованным, потребуется его реализация в классах-наследниках с последующей перекомпиляцией. | При добавлении нового метода в интерфейс мы должны определить его во всех классах, реализующих интерфейс, с перекомпиляцией. |
Члены | Может содержать все допустимые члены. | Только методы, свойства |
Вывод:
1. если есть для классов нет одинаковых методов в плане реализации, а есть только одинаковые методы в плане объявления, то лучше использовать Interface.
2. Если есть сущность действительно абстрактная и в ней можно реализовать методы для наследников, то лучше использовать abstract class.
3. Если ничего из выше перечисленного нет, то нужно сделать родительский класс от которого будите наследоваться.