[JAVA] 객체지향(3)
Abstract Class(추상 클래스)
자식 클래스에서 반드시 부모 클래스의 메서드를 재정의 해서 사용하기 때문에 부모 클래스에서의 메서드 구현이 무의미한 상황
-> 함수에 대한 정의는 있어야 하는데 몸통은 필요 없을 경우 abstract 사용. abstract 메서드는 abstract 클래스에만 있을 수 있다.
부모 클래스에서 해당 메서드의 선언부만 남기고 구현부는 세미콜론(;)으로 대체
abstract 키워드를 메서드 선언부에 추가 (구현부가 없다는 의미)
abstract 키워드를 클래스 선언부에 추가 (객체를 생성할 수 없는 클래스라는 의미)
추상 클래스의 특징
- abstract 클래스는 상속 전용 클래스이다.
- 객체를 생성할 수는 없지만 자식 클래스를 참조할 수는 있다.
- 부모 클래스에서 상속받은 abstract 메서드는 자식 중 한명은 꼭 재정의해서 사용해야하는 일종의 빚이다.
Interface(인터페이스)
사용자는 기능 구현에 관심 X
개발자는 인터페이스에 따라 내부 기능 구현에만 관심 O
- 클래스와 유사하게 interface를 선언한다.
public interface MyInterface{
...
}
- 모든 필드는 public static final이며 생략 가능
- 모든 메서드는 public abstract이며 생략 가능
- 전통적 인터페이스는 선언부만 작성 가능하지만 JDK 8에서 default method와 static method 가 추가되었다.
: default method : 객체 상태일 때 호출 가능, implements한 클래스에서 재정의 가능
static method : 클래스명, 메서드 형태로 호출 가능, 재정의 불가능
- 인터페이스는 다중 상속이 가능
- 인터페이스끼리 extends 키워드 이용하여 상속 가능
- 다형성 확장
- 모듈간 독립적 프로그래밍 가능
인터페이스를 implements 한 클래스는 모든 abstract 메서드를 Override해서 구현하거나 abstract 클래스로 표시해야 한다.
Exception Handling(예외 처리)
· 예외처리 : 예외 발생 시 프로그램의 비정상 종료를 막고 정상적인 실행 상태를 유지하는 것
· Error : 일단 발생하면 복구할 수 없다. -> 디버깅 필요
ex) 메모리부족, stack overflow
· Exception : 수습될 수 있는 비교적 약한 상태의 오류. -> 프로그램 코드에 의해 수습될 수 있는 상황
ex) 읽으려는 파일이 없음, 네트워크 연결이 안됨
· 예외 클래스 계층
- Checked Exception : 예외에 대한 대처 코드를 필수적으로 작성하지 않는다면 컴파일 진행 불가
- Unchecked Exception : 예외에 대한 대처 코드가 필수적이지 않지만 예외에 대한 책임은 개발자의 몫! 컴파일 단계에서 이상이 없었다면 unchecked exception
- Checked Exception : 예외에 대한 대처 코드를 필수적으로 작성하지 않는다면 컴파일 진행 불가
- Unchecked Exception : 예외에 대한 대처 코드가 필수적이지 않지만 예외에 대한 책임은 개발자의 몫! 컴파일 단계에서 이상이 없었다면 unchecked exception
private void printMessages(){
int i=0;
String[] greetings[] = {"Good bye", "Hi", "안녕!"};
try{
while(i<4){
System.out.println(greetings[i]);
i++;
}
}
catch(Exception e){
System.out.println("Error :" +e);
}
}
· 예외처리는 try ~ catch 구문으로 처리한다.
- 예외가 발생할 것이라 예상되는 곳을 try 블록으로 감싸기
- 예외가 발생했을 때 실행할 코드는 catch 블록에 작성
try-catch문 실행과정
- try 블록에서 예외가 발생한 경우
1) JVM이 해당 Exception 클래스의 객체 생성 후 예외 객체를 throw
2) 던진 예외 객체는 catch 블록의 argument를 통해 전달 받음, 전달 받은 예외 내용에 따라 적절하게 예외 처리 코드를 실행
3) try-catch 블록을 벗어나 다음 문장부터 정상적으로 코드 실행
- try 블록에서 예외가 발생하지 않은 경우 catch 블록을 실행하지 않고 try 블록 실행 후 다음 문장부터 정상적으로 실행
※ finally 구문은 예외 발생과 관계 없이 무조건 실행
다중 예외 처리
try 블록에서 여러 종류의 예외가 발생한 경우 하나의 try 블록에 여러개의 catch 블록 추가
· 다중 catch 문장 작성 시 순서 유의
- JVM이 던진 예외는 catch 문장 찾을 때 다형성 적용
- 상위 타입의 예외가 먼저 선언된 경우 뒤에 등장하는 catch 블록은 동작하지 못함. 컴파일 에러
- 예외 클래스 중 최상위 클래스는 Exception. 맨 마지막 catch문에 작성한다.
Throwable의 주요 메서드
public String getMessage() | 발생한 예외에 대한 구체적 메시지 반환 |
public Throwable getCause() | 예외의 원인이 되는 Throwable 객체 또는 null 반환 |
public void printStackTrace() | 예외가 발생된 메서드가 호출되기까지의 메서드 호출 스택 출력. 디버깅의 수단으로 사용 |
Throws 키워드를 통한 처리 위임
: 예외 처리를 발생한 곳이 아닌 메서드를 호출한 곳에서 처리하고 싶을 때 throws 키워드를 사용한다.
-Unchecked Exception 계열은 throws 키워드를 사용하지 않아도 예외가 전달되기 때문에 throws 키워드 생략 가능하지만 명시적으로 throws 키워드를 작성하면 코드 분석에 유용@
사용자 정의 예외
: 사용자의 필요에 의해 직접 예외 클래스를 만들 수 있다.
- 대부분 Exception 또는 RuntimeException 클래스 상속받아 작성.
- Checked Exeption : 코드 복잡하지만 예외 처리 누락 X
- Unchecked Exception : 코드 간결해지지만 예외 처리 누락 가능성 O
· 장점
- 예외 객체의 활용
- 코드의 재사용
- 코드의 간결성 향상
Collection Framework(컬렉션 프레임워크)
· Generics
: 꺼낸 객체가 뭔지 모르는 불편함을 해소. 데이터 형식에 의존하지 않고 하나의 값이 여러 데이터 타입을 가질 수 있게 한다.
- 미리 사용할 타입을 명시해서 형 변환을 하지 않아도 되게 함.
· 클래스 또는 인터페이스 선언 시 <> 에 타입 파라미터 표시
public class 클래스명<T>{ ...}
· 타입 파라미터 : 임의의 참조형 타입. (반드시 이렇게 할 필요는 없지만 암묵적 규칙)
- T : reference Type
- E : Element
- K : Key
- V : Value
※ 타입 파라미터로는 참조 타입(Reference Type)밖에 올 수 없다. int, double, char과 같은 타입 대신 Integer, Double 으로 쓴다.
· 객체 생성 시 변수 쪽과 생성 쪽의 타입은 반드시 같아야한다.
- 클래스명<String> 변수 = new 클래스명<String>();
- 클래스명<String> 변수 = new 클래스명<>(); <- 더 자주 사용
public class ClassName <T> { ... }
public class Main {
public static void main(String[] args) {
ClassName<String> a = new ClassName<String>();
}
}
· Generic Type 객체를 참조할 때 와일드카드(물음표)를 이용한다.
Generic type<T> | 타입에 제한이 없음 |
Generic type<? extends T> | T 또는 T를 상속받은 타입들만 사용 가능 |
Generic type<? super T> | T 또는 T의 조상 타입만 사용 가능 |
· 컬렉션 프레임워크
: 객체나 데이터들을 효율적으로 관리할 수 있는 자료구조들이 있는 라이브러리
<3대 주요 인터페이스>
· List(일렬로 줄서기): 순서가 있고 데이터 중복을 허용
- ArrayList
배열을 사용하여 데이터 관리
메서드들이 존재하여 데이터 추가/삭제가 간단하며 사용이 쉽다
장점 : 데이터 접근 속도가 빠르다(데이터의 인덱스 번호를 알고있는 경우)
단점 : 비 순차 데이터의 추가/삭제 속도가 느리다.
- LinkedList
Node 객체를 사용하여 데이터 관리
각 노드는 다음 노드의 주소값과 데이터로 구성
장점 : 데이터의 추가/삭제 속도 빠르다.
단점 : 데이터 접근 속도가 느리다. (첫번째 노드부터 순차적으로 검색)
- Vector
ArrayList와 동일 구조 + 동기화 된 메서드로 구성되어 멀티스레드 환경에서 안전하게 객체 추가/삭제 가능
단점 : 하나의 스레드에서 Vector 객체를 점유하는 동안 다른 스레드는 추가/삭제 불가능하여 속도가 느리다.
· Set(주머니 속 구슬) : 순서가 없고 데이터 중복 불가
- HashSet
데이터 순서 없이 저장, 중복 불가
- TreeSet
데이터 오름차순 정렬 저장(이진트리로 정렬된 상태로 요소 관리), 중복 불가
※ Set에서 동일 데이터 기준 : equals()가 true를 return, hashCode() 값이 같으면 동일 데이터
· Map(Key, Value의 쌍으로 데이터 관리) : 순서가 없고 Key는 중복 불가, Value는 중복 허용
- HashMap
스레드를 고려하지 않아 Hashtable에 비해 추가/삭제 빠르다
- TreeMap
Key 데이터 기준 오름차순 정렬 저장(이진트리로 정렬된 상태로 요소 관리)
- Hashtable
동기화된 메서드로 구성되어 있어 멀티스레드 환경에서 안전하게 객체 추가/삭제 가능
단점 : 하나의 스레드에서 Hashtable 객체를 점유하는 동안 다른 스레드는 추가/삭제 불가능하여 속도가 느리다.