공통점
1.
구현부가 작성되어 있지 않은 추상 메서드를 구현하도록 강제하는 역할을 한다.
2.
추상메서드를 갖고 있기 때문에 인스턴스화 시킬 수 없다.
차이점
•
Interface의 경우 자바 8 이후 추가된 default · static 메서드를 제외한 메서드들은 구현부가 작성되어있지 않아야 한다.
•
Abstract Class의 경우 구현부가 작성되어있지 않은 abstract method(추상메서드)가 1개 이상 존재하면 된다.
•
Interface는 다중 구현(implements)이 가능하지만, Abstract Class는 다중 상속(extends)이 불가능하다.
추상 클래스와 인터페이스의 정의 살펴보기
추상 클래스 (Abstract Class)
abstract class Sample{
abstract void run();
public void start(){ System.out.println("시작!");}
}
Java
복사
추상 클래스는 위와 같이 구현부가 없는 메서드를 갖고 있고,
구현부가 존재하지 않는 메서드는 abstract 키워드로 추상 메서드임을 명시해주어야 한다.
abstract class Sample{
//abstract 키워드 없음! 대신 {} 빈 괄호가 존재
void run(){};
public void start(){ System.out.println("시작!");}
}
Java
복사
위와 같이 추상 메서드에 abstract 키워드를 제외하고 구현부를 비워놓고 자손 클래스에서 구현하도록 해도 되지만,
abstract 키워드로 구현을 명시하면 상속받는 자손 클래스에서 꼭 구현이 필요하다는 것을 알려주는 것이 좋다.
public class Test extends Sample{
@Override
void run() { System.out.println("시작!");}
}
Java
복사
추상 클래스를 상속받은 클래스는 abstract 키워드가 붙은 추상 메서드를 무조건 구현해야하고,
그 외 추상 메서드가 아닌 메서드는 오버라이딩을 해도 되고 안해도 된다.
인터페이스 (Interface)
interface Sample{
public static final String value = "value";
void run();
static void start() { System.out.println("static 메서드!");}
default void init() { System.out.println("default 메서드!");}
}
Java
복사
인터페이스는 위와 같이 구현부가 없는 추상메서드, static 메서드, default 메서드를 갖는다.
그리고 변수는 무조건 public static final 이어야 하기 문에, 이는 제어자는 생략해도 자동적으로 추가된다.
public class Test implements Sample{
@Override
public void run() { System.out.println("시작!");}
@Override
public void init() { System.out.println("디폴트 메서드 오버라이딩!");}
}
Java
복사
인터페이스도 마찬가지로 구현하는 클래스에서 추상메서드를현해야한다.
static 메서드는 오버라이딩할 수 없지만,
default 메서드는 구현하는 클래스에서 그냥 사용할 수도 있고 오버라이딩해서 사용할 수도 있다.
여러가지 경우 테스트
다중 상속 가능? 
public class Test extends Sample,Sample2 {
@Override
void run() { System.out.println("시작!");}
@Override
void run2() { System.out.println("시작2!");}
}
abstract class Sample{
abstract void run();
}
abstract class Sample2{
abstract void run2();
}
Java
복사
추상 클래스를 여러개 상속받아서 구현이 필요한 추상 메서드들을
다 구현해주기만 하면 될 것 같지만 컴파일 에러를 일으킨다.
지금처럼 추상 메서드만 존재하면 문제가 발생하지 않지만, 일반 메서드가 존재한다고 생각해보면 이해가 잘 될 것이다.
abstract class Sample{
abstract void run();
void hello(){ System.out.println("안녕"); }
}
abstract class Sample2{
abstract void run2();
void hello(){ System.out.println("반가워");}
}
Java
복사
위와 같이, 일반 메서드 이름이 같은 클래스를 동시에 상속받은 클래스는
어떤 부모 클래스의 hello()를 동작시켜야 할 지 결정할 수 없기 때문이다.
상속의 상속 가능? 
public class Test extends Sample2 {
// Test 클래스에서 Sample2의 run2 과 Sample의 run 모두 구현
@Override
void run() { System.out.println("시작!");}
@Override
void run2() { System.out.println("시작2!");}
}
abstract class Sample{
abstract void run();
}
abstract class Sample2 extends Sample{
abstract void run2();
}
Java
복사
상속의 상속은 가능하다.
위 상황 처럼 Test 클래스에서 다 구현해주어도 되지만.
public class Test extends Sample2 {
// Sample2 의 run2 만 구현
@Override
void run2() { System.out.println("시작2!");}
}
abstract class Sample{
abstract void run();
}
abstract class Sample2 extends Sample{
abstract void run2();
// Sample의 run 구현
@Override
void run() { System.out.println("시작!");}
}
Java
복사
이런 식으로 Sample2에서 Sample 의 추상 메서드를 구현하는 것도 가능하다.
그러면 Test 클래스에서는 메서드 한개만 구현부를 작성하면 된다.
다중 인터페이스 구현 가능? 
인터페이스는 다중으로 구현할 수 있다.
public class Test implements Sample,Sample2{
@Override
public void run() { System.out.println("시작!");}
@Override
public void run2() { System.out.println("시작2!");}
}
interface Sample{
void run();
}
interface Sample2{
void run2();
}
Java
복사
구현하려는 인터페이스에 정의된 추상 메서드들을 다 구현해주기만 하면 된다.
public class Test implements Sample,Sample2{
//💡 컴파일 에러 발생! 하나는 run메서드가 void반환인데 하나는 run메서드가 int 반환임
@Override
public void run() { System.out.println("시작!"); }
}
interface Sample{
void run();
}
interface Sample2{
int run();
}
Java
복사
만약, 위와같이 Sample과 Sample2의 추상메서드의 이름은 같지만, 메서드의 반환 타입 혹은 파라미터 형식이 다른 경우에는 컴파일 에러를 일으킨다.
상속받으면서 인터페이스 구현 가능? 
package test;
public class Test extends Sample3 implements Sample, Sample2 {
@Override
public void run() { System.out.println("시작!");}
@Override
public void run2() {System.out.println("시작2!");}
@Override
public void run3() {System.out.println("시작3!");}
}
interface Sample{
void run();
}
interface Sample2{
void run2();
}
abstract class Sample3{
abstract void run3();
}
Java
복사
인터페이스 2개와 추상 클래스 하나를 상속받는것도 가능하다.
단 구현이 필요한 메서드들을 다 구현해주기만 하면 되고 위에서 설명한 원칙들을 위배하지 않으면 가능하다!