관리 메뉴

엉망진창

추상클래스(abstract class) - 인터페이스(interface) 본문

Study/Java

추상클래스(abstract class) - 인터페이스(interface)

엉망진창 2009. 6. 30. 17:00
추상클래스
인터페이스
공통점

  • 모두 클래스임
  • 하위클래스에서 모든 추상메서드를 구현해야 함
차이점

  • 추상메서드 외 일반 멤버 변수와 메서드를 가질 수 있다.
  • extends를 사용
  • 단일 상속만 가능
  • 작업의 레벨 분할을 위해서 사용

  • 추상메서드와 static final 변수만 사용
  • Implements를 사용
  • 중복 구현 가능
  • 공동 작업을 위한 상호간의 인터페이스를 위해 사용
 
클래스는 크게 일반클래스와 추상클래스로 나뉘는데 추상클래스는 본문중에 '추상메소드'가 하나 이상 포함되는 경우를 말합니다.
 
인터페이스는 모든 메소드가 추상메소드인 경우 선언하는 경우가 많습니다.
추상메소드라 함은 메소드의 선언부만 있고 본문이 없는 것을 말합니다.
여기서 본문은 중괄호({})로 묶여진 몸체(body)부분을 말하는데 중괄호 안이 비어있더라도 이것이 존재한다면 그것은 추상메소드가 아닙니다.
추상메소드의 선언의 예는 다음과 같습니다.
abstract public void test( int a );
 
즉, 메소드의 선언 후에 세미콜른(;)만을 찍어 이를 선언만 하고 구현은 자식클래스에서 하게 하는 방법입니다.
 
일반 클래스의 경우 상속받은 자식클래스가 반드시 부모클래스의 메소드를 '오버라이딩(overriding)'할 필요가 없지만 추상클래스를 상속받은 자식클래스는 반드시 추상메소드를 오버라이딩하여야 하기에 메소드를 강제로 구현하게 할 때 많이 쓰입니다.
추상클래스와 인터페이스의 가장 큰 차이점은 바로 '클래스'냐 아니냐의 차이입니다. 추상클래스는 엄연한 클래스로 이를 구현하는 것은 '상속(extends)'입니다.
그러나 인터페이스는 '구현(implements)'라는 키워드를 통해 구현하게 되는데 이는 자바에서 매우 중요한 차이를 가집니다.
 
자바는 오로지 '단일 상속'만을 지원하기 때문에 추상클래스를 상속받는 클래스는 다른 클래스를 상속받을 수 없습니다.
그러나 인터페이스를 포함하는 클래스는 다른 클래스를 상속받을 수 있습니다.
 
추상클래스는 일반클래스와 달리 그 자신을 new 명령어를 통해 객체를 생성할 수 없습니다. 그러나 '다형성(polymorlphism)'을 통해 자식 클래스의 객체를 생성할 수는 있습니다.
 
인터페이스를 쓰는 가장 큰 이유는 다중상속을 지원하지 않는 자바에서 다중상속의 장점을 가져오기 위해서입니다.
다중상속이 가지는 단점은 배제하고 오직 장점만을 취하기 위해 인터페이스를 쓰는 것입니다.

 
상속이란 개념은 부모클래스의 속성과 메소드를 자식클래스가 물려받는다는 것인데 쉽게 예를 들면 '자동차'라는 클래스는 '색깔', '배기량' 등의 속성과 '기름을 넣는다', '달린다' 등의 메소드를 가질 수 있습니다. 이 클래스를 상속하는 '승용차' 클래스는 별도로 선언하지 않아도 부모클래스의 '색깔', '배기량'이라는 속성과 '기름을 넣는다', '달린다'라는 메소드를 가지게 되죠.
 
추상클래스는 이 부모클래스가 단순히 관념적인 성격이 강할 때 많이 쓰이는데 예컨데 '새'라는 클래스는 그냥 '난다'라는 메소드를 가지지만 새의 종류에 따라 나는 방법이 조금씩 틀려 자식클래스에서 어차피 구현해야 될 부분이므로 굳이 부모클래스에서 그 내용을 구현할 필요가 없기 때문에 사용합니다.
 
요사이 추세는 굳이 클래스간의 조직을 표현할 필요가 없을 경우는 추상클래스를 쓰는 대신 인터페이스를 쓰는 경우가 많습니다. 인터페이스는 위에서 말씀드린바와 같이 모든 메소드가 추상메소드라서 이를 포함하는 클래스는 이들을 모두 구현해야 합니다.
 
추상메소드는 멤버변수(어트리뷰트)를 가지지만 인터페이스는 오직 '상수'만을 가질 수 있습니다.
 
* 추상메소드 상속과 오버라이딩
 
abstract class Employee{
String name,phone;
Employee(){}
Employee(String name,String phone){
this.name=name;
this.phone=phone;
}
public abstract String getInfo(); // abstract 추상 메소드(불구 메소드)
// 추상 클래스는 다른 클래스의 슈퍼 클래스 역활을 한다.
// 다른 클래스에 상속을 해줄 목적으로만 사용된다.
// 추상 클래스를 상속 받은 클래스에서는 상속받은 클래스를 반드시 오버라이딩해줘야 한다.
}

class C070521 extends Employee{
C070521(String name,String phone){
super(name,phone);
}
public static void main(String[] args){
Employee a = new C070521("김대경","그런거없다");
System.out.print(a.phone);
}
public String getInfo(){
return name+phone;
}
}
 
오버로딩이란?

메서드는 변수와 마찬가지로 같은 클래스 내에서 서로 구별될 수 있어야 하기 때문에 각기 다른 이름을 가져야 한다.
하지만, 자바에서는 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메서드를 정의할 수 있도록 했다.

이처럼, 한 클래스 내에 같은 이름의 메서드를 여러 개 정의하는 것을 메서드 오버로딩(Method Overloading) 또는 간단히 오버로딩(Overloading)이라 한다.

오버로딩(Overloading)의 사전적 의미는 '과적하다.
' 즉, 많이 싣는 것을 뜻한다. 보통 하나의 메서드 이름에 하나의 기능만을 구현해야하는데, 하나의 메서드 이름으로 여러 기능을 구현하기 때문에 붙여진 이름이라 생각할 수 있다. 앞으로는 메서드 오버로딩을 간단히 오버로딩이라고 하겠다.

오버라이딩이란?

조상클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다. 상속받은 메서드를 그대로 사용하기도 하지만, 자손클래스 자신에 맞게 변경해야하는 경우가 많다. 이럴 때 조상의 메서드를 오버라이딩한다.

[참고]override의 사전적 의미는 '~위에 덮어쓰다(overwrite).'
                                         또는 '~에 우선하다.'이다.

오버로딩 vs. 오버라이딩

오버로딩과 오버라이딩은 서로 혼동하기 쉽지만 사실 그 차이는 명백하다.
오버로딩은 기존에 없는 새로운 메서드를 추가하는 것이고, 오버라이딩은 조상으로부터 상속받은 메서드의 내용을 변경하는 것이다.


오버로딩(Overloading) - 기존에 없는 새로운 메서드를 정의하는 것(new)
오버라이딩(Overriding) - 상속받은 메서드의 내용을 변경하는 것(change, modify)


아래의 코드를 보고 오버로딩과 오버라이딩을 구별할 수 있어야 한다.


class Parent {
     void parentMethod() {}
}

class Child extends Parent {
     void parentMethod() {} // 오버라이딩
     void parentMethod(int i) {} // 오버로딩

     void childMethod() {}
     void childMethod(int i) {} // 오버로딩
     void childMethod() {}       // 에러!!! 중복정의 되었음.(already defined in Child)
}



 
 네이버 지식인 오픈백과 '자바 인터페이스와 추상클래스의 공통점과 차이점' 에서 'neolha'  님의 글
 인터페이스의 용도를 정확히 이해하려면 우선 상속과 구현의 차이를 이해하셔야 합니다. 이미 상속/구현이라는 말 속에 핵심 내용이 다 들어가 있습니다. 상속: 상속은 물려받는다란 뜻이에요 .. 이른바 부모로부터 무언가를 물려받아 거저 먹겠다는 것이죠 구현: 구현은 규칙이나 규격에 따라 실제를 만든다는 말입니다. .. 상속과는 정 반대로 의무가 따릅니다. 그래서 상속은 주로 새로 개발할 클래스를 쉽게 만들 수 있도록 해 줍니다. 결국 이미 구축된 개발환경(부모 클래스들)이 자식들을 돕는 것이죠. 반면에 구현(특히 인터페이스를 구현)할때는 인터페이스가 제시하는 요건을 충족시켜야 합니다. 즉 부모가 제시하는 엄격한 규칙에 맞도록 무엇인가를 만들어줘야 하는 것으로. 자식보다는 부모(이미 구축된 프래임워크)가 할 일이 편해집니다. 즉 자식들의 다양성 때문에 부모들도 그때 그때 새롭게 개발을 하거나 할 필요가 없어지기때문에 보다 추상화되고 규격화된(그래서 간단한) 프레임워크를 구축할 수가 있습니다.


출처 : 인터넷 검색. 같은 글이 꽤 있어 원본 글의 출처를 잘 모르겠습니다. 아시는 분 출처 남겨주시면 수정하겠습니다.