Зачем прописывать методы в Interface когда можно так же в классе?
Ответ явоспецифичный. Потому что один класс может реализовать сколько угодно интерфейсов, но наследуется лишь от одного класса.Ответ концептуальный. Ромбическое наследование. От А наследуются B и C, от них обоих наследуется D.
1) Если в A есть поле, в D что, это поле будет в двух экземплярах? А если оно protected и в B мы добавили метод, который его меняет?
2) Если B и C переопределяют какой-то метод foo(), как быть D? А если нужна и версия B.foo(), и C.foo(), и они обе вызывают A.foo — получатеся D.foo вызовет A.foo дважды? А если в C есть второй метод bar(), который вызывает foo() и начинает вести себя не так, как надо, если мы берём реализацию B.foo()?
В общем, множественное наследование — хорошая штука, но ромбическое — штука опасная. В языке, где любое множественное наследование неизменно ромбическое, всё, что остаётся — делать такие условия, при которых ни 1, ни 2 не сработает.
Одно из таких условий — унаследоваться от одного класса и нескольких интерфейсов. 1) У интерфейса нет полей, и 2) эталонная реализация, существующая в некоторых языках программирования, в любом случае менее приоритетна, чем конкретная реализация из класса. Вызывать ту и другую нет смысла: если программист написал свою сверх эталонной — значит, он хочет сделать то же другим путём.
Интерфейсами очень хорошо реализовывать какие-либо слушатели или коллбеки для использования их значений извне.
Например:public class MyClass {
  
  private String mess = "";
  private MyListener listener;
  
  public MyClass () {
    
    mess = "Успешно";
    
  }
  
  public void addListener (MyListener listener) {
    this.listener = listener;
  }
  
  public void connect () {
    
    listener.onSuccess (mess); // Какое-либо действие в случае успеха, например, подключение к серверу
    
  }
  
}

interface MyListener {
  
  void onSuccess (String mess);
  void onError (int code);
  
}
Теперь его можно вызвать следующим образом:MyClass myClass = new MyClass ();

myClass.addListener (MyListener () {
  
  @Override
  public void onSuccess (String var1) {
     System.out.println (var1); // var1 имеет значение "Значение", которое мы получили в конструкторе класса MyClass. А тут с ней можно делать что угодно, например, слать HTTP-запросом куда-либо дальше.
  }
  
});

myClass.connect ();
Просто и наглядно. Еще удобно их пользовать для описания методов каком-либо классе, чтобы другим программерам было удобнее копаться в чужом коде.