0

друзья!

Можете подсказать, пожалуйста, в чем отличие реализации классов в виде abstarct от interface?

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

Как я сейчас вижу, что в обоих случаях пишется сама сигнатура, без тела,а уже в наследниках идет реализация.

Не пойму разницу.

Спасибо!

Stas
  • 1
  • 1
    как и всегда было: abstract - для расширения в наследниках, interface для имплементации конкретного поведения независимо от типа (можно крыль пределать самолёту, а можно птице, а можно рыбе) – Алексей Шиманский Feb 05 '22 at 06:59
  • 1
    Ну как минимум потому, что унаследовать вы можете только один класс, а расширять интерфейсами можно сколько угодно. К тому же, абстрактный метод может иметь поля, а его методы не всегда обязаны предоставлять "обязательный контракт" – Perfect Voyage Feb 05 '22 at 07:50

1 Answers1

0

у класса есть состояние - поля типа int, boolean и т.д. и поведение - методы.

абстрактный класс - это такой недо класс, имеющий своё состояние и поведение, с условием, что мы не можем создать экземпляр этого класса и от него можем наследоваться, менять его свойства и поведение. (унаследовать можем только один класс)
интерфейс - это поведение, контракт. (расширять интерфейсами можем сколько угодно)
например есть у нас абстрактный класс студент

abstract class Student {
    abstract void toStudy();
}

и есть класс медик, который наследуется от класса студент со своей реализацией метода учиться

public class Medik extends Student {
    @Override
    void toStudy() {
        System.out.println("учусь из-за всех сил");
    }  

и есть интерфейсы бухать и курить

interface Drinkable {
    default void toDrink() {
        System.out.println("бухаю");
    }
}

interface ISmoke { void smoke(); }

и создаём класс хороший медик со своей реализацией

class GoodMedik extends Student implements ISmoke,Drinkable{
    @Override
    public void smoke() {
        System.out.println("не курю");
    }
@Override
void toStudy() {
    System.out.println("учусь нормально");
}

@Override
public void toDrink() {
    System.out.println("не бухаю");
}

}

создаём класс плохой медик

class BadMedik extends Student implements ISmoke,Drinkable{
    @Override
    public void smoke() {
        System.out.println("курю");
    }
@Override
void toStudy() {
    System.out.println("учусь плохо");
}

@Override
public void toDrink() {
    System.out.println("бухаю");
}

}

class Test{ public static void main(String[] args) { BadMedik medik = new BadMedik();

    medik.smoke();//курю
    medik.toStudy();//учусь плохо
    medik.toDrink();//бухаю

Student student = new BadMedik();

student.toStudy();//учусь плохо
}

}

а для лучшего понимания, скачай и почитай эту книжку введите сюда описание изображения

она на 300 страниц, про ооп там около 150стр.
Объектно-ориентированное мышление Мэтт Вайсфельд

ещё пример с коллекциями

class Test {
    public static void main(String[] args) {
// создаём через интерфейс связный список
        List<String> list = new LinkedList<>();
        list.add("1111");
//через интерфейс меняем реализацию 
        list = new ArrayList<>(list);
        list.add("222");
    }
}
  • А зачем дефолт в интерфейсе? Я тут подумал немного и решил, что надо порекомендовать разработчикам языка добавить abstract на interface, чтобы нельзя было такого делать. – Roman C Feb 05 '22 at 11:00
  • Большое спасибо! Книгу обязательно прочту! Сейчас штудирую шилдта и дударя на ютуб. – Stas Feb 05 '22 at 13:46
  • @RomanC в целом было сделано это для лямбд. в ответах дубликатах гляньте – Алексей Шиманский Feb 05 '22 at 14:10