추상클래스와 인터페이스
01 추상 클래스와 추상 메서드
package section11;
class Animal {
void cry() {} // 텅 빈 메서드
}
class Pig extends Animal {
@Override
void cry() {
System.out.println("꿀꿀");
}
}
…
calss Farm {
void sound(Animal animal) {
animal.cry(); // 매개변수 참조 객체의 오버라이딩된 메서드 호출
}
}
-Animal 클래스의 cry() 메서드가 텅 비어있는것을 확인할 수 있다.
-Animal 객체를 통해서 직접 cry() 메서드를 호출할 일은 없었지만, Animal 클래스를 상속받은 자식 클래스들이 cry() 메서드를 오버라이딩하여 재정의하고, 타입 변환을 통해서 그 메서드를 각각 사용하기 위함이었다.
1 추상 메서드 (abstract method)
-다형성을 위해 메서드의 선언은 통일해야 하지만, 실제로 구현하는 내용은 자식 클래스마다 달라야 할 때,
부모 클래스의 메서드는 비워두고 자식 클래스에서 오버라이딩하여 구현해낼 수 있다.
-선언부만 작성하고 구현부는 작성하지 않고 남겨둔 미완성 메서드를 '추상 메서드'라고 한다.
-추상 메서드를 선언할 때는 abstract 키워드를 함께 표기해야 한다.
[메서드 구현부인 중괄호{} 대 추상 메서드를 선언하는 방법]
▶[접근제한자] abstract 반환 타입 메서드 이름 (매개변수1, 매개변수2,…);
-Animal 클래스의 cry() 메서드를 추상 메서드로 수정하면
public class Animal {
abstract void cry();
}
▶에러 메시지 : The abstract method cry in type Animal can only be defined by an abstact class
▶'abstract 메서드는 반드시 abstract class 안에 정의되어야 한다'
[추상 메서드의 형태를 갖추게 되면 따라야 하는 제약조건]
▷추상 메서드를 1개 이상 선언하면, 그 클래스는 추상 클래스로 선언되어야 한다.
※ 추상(abstract)의 사전적 의미 : 구체성 없이 일반적인 것
2 추상 클래스 (abstract class)
-하나 이상의 추상 메서드를 포함하는 클래스를 가리켜 추상 클래스라고 한다.
-추상 클래스는 추상 메서드를 포함하고 있다는 것을 제외하고는 일반 클래스와 다르지 않다.
-추상 클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있다.
[추상 클래스를 선언하는 방법]
[접근 제한자] abstract class 클래스 이름 {
// 필드
// 생성자
// 메서드 (추상 메서드 포함)
}
[추상 클래스로 선언되는 클래스의 제약 조건]
▷일반 클래스처럼 독립적으로 생성자를 호출해 객체를 생성할 수 없다.
▷자식 클래스의 생성자에서 super()를 통해 추상 클래스의 생성자를 호출하여 부모 객체를 생성한 후 자식 객체를 생성한다.
※추상 클래스가 반드시 추상 메서드를 가져야하는건 아니다.
[추상 메서드가 선언된 추상 클래스의 힘]
▷추상 클래스를 상속받은 모든 자식 클래스는 반드시 추상 메서드를 오버라이딩 및 재정의하여 구현해야한다.
→ 그렇지 않으면 컴파일 에러가 발생한다.
3 추상 클래스와 추상 메서드의 용도
-자식 클래스 간의 공통적인 필드와 메서드 이름을 통일할 수 있다.
-반드시 구현해야 하는 메서드를 선언함으로써 공통 규격을 제공한다.
[추상 클래스의 용도]
-전구 규격은 동일하고 색상이나 유리 모양만 다른 것처럼, 추상 클래스는 A,B,C 클래스에 동일한 규격을 제공하고 자식 클래스들은 각각
독립적인 메서드를 가질 수 있다.
02 인터페이스 구현
-모든 메서드가 추상 메서드인 일종의 추상 클래스를 우리는 '인터페이스'라고 부른다.
-인터페이스는 추상 메서드와 상수로만 이루어져 있으며, 추상 클래스와 마찬가지로 스스로 객체를 생성할 수 없다.
-언뜻 보면 인터페이스와 추상 클래스가 같은 역할을 하는 것처럼 느껴질 수 있지만, 취지는 완전히 다르다.
[추상 클래스]
-클래스들의 공통 메서드를 추출해 선언하며, 자식 클래스들이 상속(extends)받아 구현하도록 합니다.
-(자식 클래스들에게 기본 틀과 공통 기능을 제공)
[인터페이스]
-구현 클래스들의 기본 틀을 제공하면서, 다른 클래스 코드들과의 사이에서 중간 매개 역할을 한다.
-추상 클래스는 자식 클래스들의 공통적 특징을 추출하고 제공하는 것이 주된 역할이었다면, 인터페이스는 그뿐 아니라 다른 클래스 코드들과의
중간 매개 역할을 하는 것을 중점으로 생각할 수 있다.
1 인터페이스 선언
-인터페이스는 클래스가 아니다.!
-클래스는 객체를 만들기 위한 설계도 역할을 하는 코드의 블록을 클래스라고 부른다.
-추상 클래스는 스스로 객체를 생성할 수는 없지만, 자식 클래스의 생성자를 통해 객체를 생성해낼 수 있었다.
-하지만 인터페이스는 어떤 형태로도 객체를 만들 수 없기 때문에 클래스라고 부를 수 없다.
[인터페이스 선언 방법]
[접근 제한자] interface 인터페이스이름 {
…
접근 제한자 abstract 메서드이름(매개변수1, 매개변수2, …)
…
}
-인터페이스는 필드와 생성자를 가지지 않느다.
-이는, 객체를 생성할 수 없기에, 필드에 값을 수정할 수도 없고 생성자도 필요 없기 때문이다.
-인터페이스는 오직 추상 메서드와 상수만을 포함할 수 있다.
-인터페이스를 선언하는 방법은 클래스를 작성하는 방법과 동일하며 class 키워드 대신 interface를 작성한다.
-또한 인터페이스의 추상 메서드는 다른 클래스들과의 매개체 역할을 하므로 누구나 접근할 수 있어야한다.
-그래서 항상 public으로 구현해야 한다.
-만약 접근 제한자를 default로 구현했다면 자동으로 public으로 인식한다.
-클래스와 달리 인터페이스의 모든 필드는 public/static/final 이어야하며, 모든 메서드는 public/ static 이어야 한다.
상수 선언
-인터페이스에서는 필드 대신 상수를 선언할 수 있어야한다.
-단, 상수이기 때문에 인터페이스는 고정된 값만 선언할 수 있어 충분히 고민하고 선언해야한다.
[상수 선언 방법]
◈특징
-public : 인터페이스는 다른 클래스들의 접근이 가능해야 하므로 public 을 작성한다.
-static : 객체가 생성되지 않는 인터페이스기때문에, 내부 상수에 접근하려면 클래스 변수처럼 static으로 선언되어 메모리에 올라가있어야한다.
-final : 상수를 뜻하는 키워드이다.
[상수 명명 규칙]
-영문 대문자로 작성해야한다.
-2개 이상의 단어를 조합할 때는 언더바(_)로 연결한다.
03 인터페이스 사용
-추상 클래스는 앞에서 확인한 것처럼 추상 메서드가 비어있기 때문에 객체 생성을 스스로 할 수 없다.
-대신 자식 클래스의 생성자의 힘을 빌려 객체 생성을 할 수 있었다.
-추상 클래스와 마찬가지로, 인터페이스 역시 추상 메서드가 비어있기 때문에 객체 생성을 스스로 할 수 없다.
-따라서 인터페이스도 자신이 가지고 있는 추상 메서드를 구현해 줄 클래스를 작성해야한다.
-이렇게 인터페이스를 구현해 주는 클래스를 '구현 클래스'라고 한다.
-추상 클래스는 자식 클래스들이 상속받아 구현하지만, 인터페이스에서는 구현된 멤버들을 상속받는 의미가 아니기 때문에
상속이라는 단어를 사용하지 않는다.
-따라서 자식/부모 클래스라는 용어도 사용하지 않는다.
-"구현한다"라고 한다.
-구현 클래스는 인터페이스를 사용해 구현하겠다는 선언을 해야한다.
-구현한다는 의미를 가지고 있는 implements 키워드를 사용하여 명시할 수 있다.
-인터페이스의 모든 추상 메서드를 오버라이딩하지 않으면 에러가 발생한다.
-즉, 인터페이스를 구현하려면 모든 추상 메서드를 구현해야한다.
-만약 추상 메서드를 오버라이딩한 메서드의 접근 제한자를 public으로 지정하지 않으면 에러가 발생한다.
-즉, 구현 클래스에서 추상 메서드를 구현할 때는 반드시 접근 제한자를 public으로 지정해야한다.
-인터페이스의 상수를 가져와 사용하려면 호출해야한다.
▶인터페이스 이름.상수 이름
[인터 페이스 장점]
▷실제 구현 클래스의 내용을 전혀 보지 않고도 개발 코드로 객체를 사용할 수 있다. => 정보 은닉
▷구현 클래스들이 독립적으로 구현되고 사용될 수 있다.
개발 코드에서 객체 변경이 필요할 때, 개발 코드의 수정을 최소화할 수 있다. => 모듈화
[추상 클래싀와 인터페이스의 공통점]
▷추상 클래스와 인터페이스는 각각의 장점을 가지고 있지만, 사실 서로의 장점을 공유하기도 한다.
▷정보 은닉, 모듈화, 추상화 등은 추상 클래스와 인터페이스가 공통으로 가진 장점이다.
▷추상 클래스의 특징이 추상화와 모듈화에 중점을 맞췄다면, 인터페이스는 추상화의 특징을 가지고 있지만 정보 은닉과 모듈화에
좀 더 초점을 맞췄다고 할 수 있다.
▷추상 클래스와 인터페이스 모두 다형성을 구현할 수 있는 기반을 제공하며, 추상 메서드 구현에 대한 강제성을 반영하고 있다.
다중 인터페이스 구현
-하나의 클래스로 여러 개의 인터페이스를 구현할 수 있다.
-다중 인터페이스를 선언하는 방법은 간단하다.
-implements 키워드 뒤에 인터페이스 이름을 기재할 때 콤마(,)를 이용해 여러 개를 붙여 선언한다.
-단, 선언한 모든 인터페이스에 대한 추상 메서드를 모두 구현해야한다.
04 인터페이스 상속
-인터페이스끼리 상속 관계를 만들 수 있다.
-클래스의 상속과 마찬가지로 extends 키워드를 사용하며, 다중 상속이 가능하기 때문에 콤마(,)를 이용한다.
-클래스의 상속과 마찬가지로 인터페이스 상속을 선언하면, 하위 클래스는 상위 클래스의 모든 멤버를 상속받게 된다.
-만약 하위 인터페이스를 구현하는 클래스가 있다면, 해당 클래스는 하위 인터페이스의 추상 메서드를 포함하여
상위 인터페이스의 추상 메서드까지 구현해야한다.