예를 들어 public void aa( ) { system.out.println("가나다라"); } 처럼 메소드의 타입으로 void를 사용하는 경우에는 리턴 값을 반환 할 필요 없이 메소드를 사용할 수 있습니다. 하지만 public String bb( ) { return "가나다라"; } 같은 경우에는 메소드의 타입으로 String을 사용했죠? 이런 경우에는 리턴 값이 존재 해야 하는 겁니다. 즉 메소드의 타입이 void인경우에는 return값이 없다. 그 외에 타입들 ex) String, int, String[]들은 return값이 존재해야한다. 이렇게 이해하시면 될거 같습니다.
비슷해도 좀 다르죠 추상 개념은 구체적인 내용이 없는 개념을 나타내며 인터페이스나 추상 클래스를 통해 정의되고 하위 클래스에서 구현되는데. 오버라이딩은 상속 관계에서 상위 클래스의 메서드를 하위 클래스에서 재정의하여 다형성을 구현하는 개념이니까 메서드의 재정의와 관련되는 거죠. 이건 직접 많이 사용해봐야 차이를 느낄 수 있을거 같아요
협업을 할때 지금같이 자식클래스에서 디자인이나 로직을 선택해서 중요한 목적을 실행할때가 있을텐데 그때 추상화 제어자가 상위클랫스에 포함되어있다면 상위클래스를 인스턴스로 잘못 올리는 일을 배제할수 있습니다. 누가 전달받든 이 클래스는 하위클래스에서 선택할 부분이 있음을 한눈에 명시할 수 있는 장점이있고 첨부터 선택을 안하면 실행조차 안되게 해놓는 인터페이스는 나중에 "아 이런것도 있었네" 하는 인터페이스보단 나은거같슴니다