인터페이스 (Interface) / 추상 클래스 (Abstract Class)
- 자바에서 .class 파일을 만들 수 있는 것에는 class, interface, abstract class가 있다.
- 인터페이스에는 몸통이 없는 메소드가 선언만 되어져 있다.
- ex) public boolean equals(Object o);
- 해당 메소드를 사용하는 사용자의 입장에서는 내부 구현이 어떻게 되어 있는지 별로 궁금하지 않고 원하는 메소드를 호출하면 답을 받는 것이 중요하다.
- DAO 패턴 (Data Access Object)
- 데이터를 저장하는 저장소에서 원하는값을 요청하고 응답받는 역할.
- 비지니스 로직과 DB를 분리하기 위해 사용하는 패턴으로 DB 접근을 전담한다.
- 인터페이스와 추상 클래스를 사용하는 이유
- 설계시 선언해 두면 개발할 때 기능 구현에만 집중할 수 있다.
- 개발자 역량에 따른 메소드 명, 매개 변수 선언의 격차를 줄일 수 있다.
- 공통 인터페이스 / 추상 클래스를 선언해 놓으면 선언과 구현을 구분할 수 있다.
방법론
- interface와 abstract class를 알기 위해 시스템 절차를 알아야한다.
- 어떤 시스템을 개발하든 "방법론"을 사용해 개발한다.
- 시스템을 어떻게 만들 것인지 절차를 설명하고 어떤 문서(산출물)를 작성해야 하는지를 정리해 놓은 공동 절차.
- 방법론에도 다양한 종류가 있다.
- 일반적인 방법론 절차
- 분석
- 시스템을 분석하는 단계
- 시스템을 만들어 달라고 한 사람들에게 어떻게 개발하기를 원하는지 물어본다.
- 이런 과정을 요구사항 분석이라고 하며 분석에서 가장 주된 작업.
- 설계
- 분석 단계에서 만든 대략적인 그림을 프로그램으로 만들 수 있도록 설계하는 작업
- 어떤 메소드를 만들 것인지, 데이터를 어떻게 저장할지 세부적인 것을 정한다.
- 개발 및 테스트
- 설계 단계에서 만들기로 한 것들을 개발하는 단계
- 실제 시스템에서 제공하는 기능들을 만드는 "개발"
- 필요한 기능들이 제대로 동작하는지 확인하는 "테스트" 작업
- 시스템 릴리즈
- 사용자들에게 시스템을 제공하는 단계
- 운영 / 유지보수 단계를 거치면서 추가적으로 문제를 고쳐 나간다.
- 분석
인터페이스 (Interface)
public interface MemberManager {
public boolean addMember(MemberDTO memberDTO);
public boolean removeMember(String name, String phone);
public boolean updateMember(MemberDTO memberDTO);
}
- 인터페이스 선언부는 public class가 아닌 pulbic interface로 시작한다.
- interface 내부에 선언된 메소드들은 몸통(body)가 있으면 안된다.
- 메소드 선언 후 중괄호가 존재하거나 / 중괄호 안에 한 줄의 코드도 존재해서는 안된다.
- static / final 메소드가 존재하면 안된다.
- 인터페이스 소스 파일 이름과 클래스 파일 이름만 보면 인터페이스인지 클래스인지 알 수 없다.
- 프로젝트마다 표준을 잡아서 인터페이스 소스 파일 이름을 결정한다.
public class MemberManagerImpl implements MemberManager {
}
- 만들어져 있는 인터페이스를 구현(적용)하는 경우
- 클래스 선언문에서 클래스 명 뒤 implements 키워드를 쓴 후 인터페이스들을 나열한다.
- 인터페이스는 상속 개념이 아니고 구현의 개념이므로 여러 개를 implements 할 수 있다.
- 인터페이스에 정의된 메소드들을 구현해줘야한다!
- 정의된 메소드들을 모두 구현해줘야 컴파일이 정상적으로 수행된다.
public class InterfaceExample {
public static void main(String[] args) {
MemberManager member = new MemberManager(); // 인터페이스는 구현된 것이 아니므로 컴파일 에러 발생
// 인터페이스에 선언된 것들을 구현한 클래스를 사용한다. (클래스 형 변환)
MemberManager member = new MemberManagerImpl(); // 정상 실행
}
}
- 인터페이스를 그대로 사용해 객체를 생성하면 인터페이스는 구현된 것이 하나도 없기에 컴파일 에러가 발생한다.
- 인터페이스의 모든 메소드들을 구현한 클래스의 객체로 생성한다. (클래스 타입은 인터페이스명으로)
- 겉보기에는 인터페이스 타입처럼 보이지만 실제 객체의 타입은 인터페이스를 구현한 클래스 타입
추상 클래스 (Abstract Class)
- abstract는 "추상적인"이라는 의미를 가지고 있다.
- abstract 클래스는 자바에서 마음대로 초기화하고 실행할 수 없도록 되어있다.
- 그렇기에 abstract 클래스를 구현해 놓은 클래스로 초기화 및 실행이 가능하다.
public abstract class MemberManagerAbstract {
public abstract boolean addMember(MemberDTO memberDTO);
public void printLog(String data) {
System.out.println("Data = " + data);
}
}
- abstract 클래스는 선언 시 abstract class 키워드를 사용한다.
- 몸통이 없는 메소드 선언문에는 abstract 키워드를 명시해준다.
- abstract 키워드로 선언한 메소드가 하나라도 있는 경우 abstract 클래스로 선언한다.
- abstract 클래스 안에는 abstract 메소드가 0개 이상 있을 수 있다.
- abstract 클래스 안에 abstract 메소드가 없어도 된다.
- abstract 메소드가 있다면 무조건 그 클래스는 abstract 클래스다.
- abstract 클래스 안에 static / final 메소드가 존재해도 된다.
- abstract 클래스는 구현이 아닌 상속의 개념이다.
- 내부에 구현된 메소드가 있을 수 있기 때문
- implements가 아닌 extends로 상속 (다중 상속은 불가)
- abstract 클래스를 상속받을 때 모든 abstract 메소드는 반드시 구현!
- 인터페이스 선언하다보면 미리 만들 수 있는 메소드나 아주 공통적인 기능을 미리 구현할 수 있는 경우 해당 클래스를 따로 만들기는 번거롭고 애매할 때 abstract 클래스를 사용한다.
Final 키워드
- final은 클래스 / 메소드 / 변수에 선언할 수 있다.
public final class FinalClass {
}
- 클래스에 final을 선언하는 경우
- 접근 제어자와 class 사이에 추가할 수 있다.
- 클래스가 final로 선언되어 있으면 상속을 해줄 수 없다.
- 더 이상 확장해서는 안되는 클래스 / 누군가 이 클래스를 상속을 받아서 내용을 변경해서는 안되는 클래스를 선언할 때 final로 선언한다.
public abstract class FinalMethodClass {
public final void printLong(String data) {
System.out.println("Data = " + data);
}
}
- 메소드에 final을 선언하는 경우
- 메소드가 final로 선언되어 있으면 오버라이딩할 수 없다.
- 클래스와 같은 이유로 final 사용한다.
public class FinalVariable {
final int instanceVariable = 1;
}
- 변수에 final을 선언하는 경우
- 변수가 final로 선언되면 값을 더 이상 바꿀 수 없다. ( = 상수) (초기화 이후 할당 불가능)
- 인스턴스 변수 / 클래스 변수는 선언과 동시에 값을 지정해야 한다.
- 변수 생성과 동시에 초기화 작업 진행
- 매개 변수 / 지역 변수의 경우
- 매개 변수는 이미 초기화가 되서 넘어온다.
- 지역 변수는 선언하는 중괄호 내에서만 참조되므로 다른 곳에서 변경할 일이 없다.
public class FinalReferenceType {
final MemberDTO dto = new MemberDTO();
public static void main(String[] args) {
FinalReferenceType type = new FinalReferenceType();
type.checkDTO();
}
public void checkDTO() {
dto = new MemberDTO(); // final로 선언된 객체를 재할당했기에 컴파일 에러
dto.name = "Sangmin"; // final 객체라해서 클래스의 클래스 / 인스턴스 변수는 final이 아니다.
}
}
- 참조 자료형에 final을 선언하는 경우
- 참조 자료형도 final로 선언함과 동시에 초기화해야한다.
- 기본 자료형과 마찬가지로 두 번 이상 값을 할당하거나 새로 생성자를 사용해 초기화할 수 없다.
- 하지만 해당 객체(클래스)가 final이라고 해서 클래스의 클래스 변수 / 인스턴스 변수까지 final은 아니다.
열거형 클래스 (ENUM)
ex) ENUM class Example
public enum OverTimeValues {
THREE_HOUR,
FIVE_HOUR,
WEEKEND_FOUR_HOUR,
WEEKEND_EIGHT_HOUR
}
- 어떤 클래스가 상수(고정된 값)만으로 만들어져 있을 경우 class라고 선언하는 부분에 enum으로 선언할 수 있다.
- enum으로 선언 시 "이 객체는 상수의 집합"임을 명시적으로 나타내는 것이다.
- enum 클래스는 어떻게 보면 타입이지만, 클래스의 일종이다
- enum 클래스의 상수들은 별도로 타입과 값을 지정할 필요 없다.
- 상수들의 이름만 콤마로 구분해 나열해준다.
- 상수들만 선언하는 경우 ;(세미콜론)도 필요없다.
- enum 클래스를 가장 효과적으로 사용하는 방법은 switch 문에서 사용하는 것.
// Enum 클래스 OverTimeValues와 상수 THREE_HOUR가 있다고 가정
OverTimeValues value = OverTimeValues.THREE_HOUR;
- enum 클래스 객체 생성 방법
- enum 클래스명 객체명 = enum 클래스명.상수명;
- enum 클래스는 생성자를 만들 수 있지만, 생성자를 통해 객체를 생성할 수는 없다.
public enum OverTimeValues2 {
THREE_HOUR(18000),
FIVE_HOUR(30000),
WEEKEND_FOUR_HOUR(40000),
WEEKEND_EIGHT_HOUR(60000);
private final int amount;
OverTimeValues(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
}
- enum 클래스의 각 상수들의 값을 지정해줄 수 있다.
- enum 클래스도 생성자를 사용할 수 있지만 생성자에 package-private / private 접근 제어자만 사용할 수 있다.
- public / protected 생성자로 사용하면 안된다.
- 각 상수를 enum 클래스 내에서 선언할 때에만 이 생성자를 사용할 수 있다.
- enum 클래스도 생성자를 따로 만들어주지 않으면 생성자를 자동 생성해준다.
- enum 클래스도 마찬가지로 메소드를 선언해 사용할 수 있다.
- enum 클래스 사용 시 선언 자체는 간단하지만 구현이 복잡해진다.
- 값이 변경되는 경우 프로그램을 수정 후 중지 했다가 다시 시작해야한다는 단점이 존재
- 성능 측면에서는 훨씬 좋다.
- java.lang.Enum 클래스의 상속을 받는다.
- java.lang.Enum도 Object 클래스의 자식 클래스이므로 Object 클래스 메소드 사용이 가능하다.
- 하지만 Enum 클래스 개발자들이 hashCode(), equals(), clone()과 finalinze 메소드를 오버라이딩 하지못하게 막아놨다.
- Enum 클래스에서 toString() 사용 시 상수 이름을 출력하지만 필요에 따라 오버라이딩 가능하다.
- Enum 클래스의 메소드
- compareTo() 메소드
- Enum이 선언된 순서대로 상수들의 순서가 정해지는데 그 순서를 비교하는 메소드다.
- 메소드의 매개 변수인 상수를 기준으로 앞에 있으면 음수, 뒤에 있으면 양수를 리턴한다.
- values() 메소드
- API 문서에 없는 특수한 메소드다.
- enum 클래스에 선언되어 있는 모든 상수를 배열로 리턴하는 메소드다.
- compareTo() 메소드
간단 내용 정리
1. 인터페이스에 선언되어 있는 메소드는 body(몸통)이 있어도 되나요?
ㅡ> X, 인터페이스에서는 메소드 선언만 가능하다.
2. 인터페이스를 구현하는 클래스의 선언시 사용하는 예약어는 무엇인가요?
ㅡ> implements
3. 메소드의 일부만 완성되어 있는 클래스를 무엇이라고 하나요?
ㅡ> abstract class (추상 클래스)
4. 위에 있는 문제의 답에 있는 클래스에 body(몸통)이 없는 메소드를 추가하려면 어떤 예약어를 추가해야 하나요?
ㅡ> abstract
5. 클래스를 final로 선언하면 어떤 제약이 발생하나요?
ㅡ> 상속을 해줄 수 없다. extends 불가
6. 메소드를 final로 선언하면 어떤 제약이 발생하나요?
ㅡ> override 불가
7. 변수를 final로 선언하면 어떤 제약이 발생하나요?
ㅡ> 값을 변경할 수 없다. 변수 선언과 동시에 초기화 작업을 수행해야 한다.
8. enum 클래스 안에 정의하는 여러 개의 상수들을 나열하기 위해서 상수 사이에 사용하는 기호는 무엇인가요?
ㅡ> , (콤마)
9. enum 으로 선언한 클래스는 어떤 클래스의 상속을 자동으로 받게 되나요?
ㅡ> java.lang.Enum
10. enum 클래스에 선언되어 있지는 않지만 컴파일시 자동으로 추가되는. 상수의 목록을 배열로 리턴하는 메소드는 무엇인가요?
ㅡ> values() 메소드
출처: 이상민, <자바의 신 VOL.1> 로드북
'Java > 자바의 신 VOL.1' 카테고리의 다른 글
15. String (0) | 2024.06.25 |
---|---|
14. 다 배운 것 같지만, 예외라는 중요한 것이 있어요 (0) | 2024.06.24 |
12. 모든 클래스의 부모 클래스는 Object에요 (0) | 2024.06.21 |
11. 매번 만들기 귀찮은데 누가 만들어 놓은 거 쓸 수 없나요? (0) | 2024.06.21 |
10. 자바는 상속이라는 것이 있어요 (0) | 2024.06.21 |