2021.10.29(금)
🌿 객체 지향 프로그래밍
🌱 추상클래스
- 표현법:
접근제한자 abstract class 클래스이름
(abstract: 예약어로써, 추상클래스, 추상메소드 선언 시 붙임) - 추상메소드가 존재하는 순간 추상클래스로 정의됨 → abstract라는 예약어를 사용해서 정의해야 함
- 객체 생성이 불가능함
- 부모 클래스 구실은 가능 → 다형성 적용 가능
- 추상 클래스 = 미완성 설계도, 구체적인 구현을 빼버리고 추상화만 한 것
- 추상 클래스 = 추상메소드 + 일반필드 + 일반메소드 → 3가지 모두 생략 가능, 개발자의 역량/판단에 따라 추상 메소드가 없어도 추상 클래스로 정의 가능
- 사용 examples
- 개념적으로 개발자가 판단했을 때 해당 클래스가 아직 구체적으로 덜 구현된 상태인 것 같을 때
- 기술적으로 개발자가 판단했을 때 이 클래스는 객체 생성이 불가능해야 할 때
- 추상 메서드 사용 시 메서드 사용의 통일성 확보 가능, 표준화된 틀 제공 ← 상속받은 자식클래스는 반드시 미완성/추상 메소드를 완성시켜야 함
public abstract class Sports {
private int people; // 선수 숫자
public Sports() {}
public Sports(int people) {
this.people = people;
}
public int getPeople() {
return people;
}
public void setPeople(int people) {
this.people = people;
}
@Override
public String toString() { // toString을 오버라이딩 받아서 쓴다는 의미; 자식클래스에서는 toString() 안 씀
return "people : " + people;
}
// 추상메소드 (vs 구체클래스(구현을 구체적으로 해 둔 것))
// 표현법: 접근제한자 abstract 반환형 메소드이름();
public abstract void rule(); // 메소드 선언했는데, 메소드 signature만 있고, 메소드의 몸통(body, code block) 없음
// 자식들에게 자료형을 나눠주기 위한/다형성을 위한 용도로만 사용, Sports의 부모클래스로서만 존재 ← 규칙이 없는 Sports 종목은 없음
// method body가 존재하지 않는 미완성 메소드 → 미완성 메소드가 하나라도 포함되는 순간 해당 클래스는 미완성(추상) 클래스가 됨 → 해당 클래스명 앞에도 abstract 예약어 씀
}
🌱 인터페이스
- 상수 필드와 추상 메소드만으로 이루어진, 추상 클래스의 변형체(인터페이스는 클래스가 아님)
- 표현법:
접근제한자 interface 인터페이스이름 {
상수 필드 // 인터페이스의 모든 필드들은 암묵적으로 public + 상수 필드(키워드 static final -> static 메모리 영역에 프로그램 시작 시 할당되어 프로그램 종료 시까지 존재, 프로그램 동작 중에 같은 이름의 변수가 생길 일 없음)
추상 메소드 // 인터페이스의 모든 메소드들은 암묵적으로 public + abstract
}
- 무조건 구현해야 하는 것이 있을 때 인터페이스에 틀만 만들어두고 상속하게 됨
- 추상 클래스보다 좀 더 강한 규칙성/강제성을 가짐
- Java에서는 메소드 및 필드 충돌 때문에 단일 상속(한 번에 한 번 상속)만 가능 vs 인터페이스는 다중 상속을 허용/다중 상속해도 문제 발생 여지 없음(메소드가 겹치더라도 최종 구현 부분은 실제 구현 클래스에서 기술하기 때문에)
- 인터페이스 간의 상속 관계:
자식인터페이스 extends 부모인터페이스1, 부모인터페이스2..
(다중 가능)
추상 클래스 vs 인터페이스
공통점
- 객체 생성은 안 되나, 참조변수로 사용은 가능(-> 다형성 적용 가능)
- 상속하는 클래스에 추상 메소드를 오버라이딩(추상 메소드의 몸통 구현)하도록 강제
- 추상클래스도 추상클래스를 상속할 수 있고, 인터페이스는 인터페이스를 상속할 수 있음
차이점: 존재하는 목적이 다름
- 추상 클래스: 클래스 멤버로 변수 및 함수 생성이 가능하고, 추상 메소드가 포함되어 있거나 abstract 키워드를 통해 정의됨 -> 추상 클래스를 상속받아 기능을 이용하고 자식 클래스에서 클래스 확장해서 씀
- 인터페이스: 모든 필드는 상수 필드 + 모든 메소드는 추상 메소드로 정의 -> 클래스의 기능/메소드 구현을 강제하기 위해 사용 -> 구현을 강제함으로써 구현 객체의 같은 동작을 보장할 수 있음
- extends(상속받다, 클래스 간의 상속 관계,
자식클래스 extends 부모클래스
) vs implements(구현하다, 클래스와 인터페이스의 구현 관계,클래스 implements 인터페이스
)
🌿 예외처리
errors(오류)의 종류
- 시스템 에러: 컴퓨터의 오작동으로 인해 발생하는 에러 -> 소스코드로 해결이 안 됨; 심각함..
- 컴파일 에러: 프로그램 실행 전 소스코드 상의 문법적인 문제로 발생하는 에러 -> 빨간줄로 알려줌 -> 소스코드 수정으로 해결
- 런타임 에러: 프로그램 실행 중 발생하는 에러; 소스코드 상 문법적인 문제가 없는데 발생(빨간줄 안 생김) <- 개발자가 예측 가능한 경우 제대로 처리를 안 해 놓았을 경우 ou 사용자의 잘못일 경우(버그)
- 논리 에러: 소스코드 상 문법적인 문제도 없고, 실행했을 때도 굳이 문제가 발생하지 않지만, 프로그램 의도 상 맞지 않음; 기획과 설계(내가 가진 도구들을 가지고 어떻게 만들지 고민)가 잘못된 경우 발생; 찾는 데 시간 아주 오래 걸림
예외: 시스템 에러를 제외한 나머지(컴파일, 런타임, 논리 에러) 비교적 덜 심각한 에러들; 개발자가 해결 가능함; 프로그램을 만든 개발자/프로그래머가 예상한 정상적인 처리에서 벗어나는 경우
- exception 클래스를 상속받는 클래스 = checked exception
- RunTime exception(프로그램 실행 시 발생되는 예외들) 클래스를 상속받는 클래스 = unchecked exception -> 빨간줄 안 뜸, 개발자가 완벽하게는 아니더라도 어느 정도 예측이 가능함 -> 조건문으로 해결 가능함 -> 굳이 예외처리 할 필요 없음
e.g. ArrayIndexOutOfBoundsException: 배열의 부적절한 index로 접근할 때 발생하는 예외
NegativeArraySizeException: 배열의 크기를 음수로 지정할 경우 발생하는 예외
ClassCastException: 상속 구조가 아닌 경우 등 허용할 수 없는 형변환이 진행될 경우 발생하는 예외
NullPointerException: 객체를 참조했더니 주소값이 null이 들어있을 경우 발생하는 예외
ArithmeticException: 나누기 연산 시 0으로 나누면 발생하는 예외 등
예외 처리: 오류 발생을 막기 위해서(x) 예외들이 발생했을 경우를 대비해서 -> 예외가 발생하더라도(오류 발생은 막을 수 없음) 잘 동작하도록 하기 위해(o) 예외 처리는 항상 해줘야 하고, 하는 방법은 많음 -> 상황에 따라 다름
예외 처리 방법
- 조건문
- try ~ catch문
- 다중 catch block
- throws 등
public class B_CheckedException {
/* CheckedException: 문법적으로 반드시 예외 처리를 해줘야 하는 예외들; 빨간 줄 나옴
* 예측 불가능한 곳에서 발생 -> 미리 예외처리 구문을 작성해야 함
* 주로 외부 매체와 어떤 입출력 시 발생
*/
public void method1() { // 메소드2 호출
try {
method2();
}
catch(IOException e) {
System.out.println("IOException 예외 발생함");
}
}
public void method2() throws IOException { // 문자열 입력받는 메소드
System.out.print("아무 문자열이나 입력해주세요~");
// Scanner와 같이 키보드로 값을 입력받을 수 있는 객체(단, 문자열로만 가능)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// String str = br.readLine(); // 아래 예외처리 안 하면 "Unhandled exception type IOException(이 메소드 호출 시 IOException 발생할 수도 있음을 알려줌)" error 발생 -> 예외 처리 반드시 해줘야 문제없이 실행됨
// 방법1) try ~ catch: 내가 해결하겠다
try { // 문제 발생 여지가 있는 부분을 try 블럭{} 안에 넣음
String str = br.readLine();
System.out.println("문자열의 길이 : " + str.length());
}
catch(IOException e) {
System.out.println("IOException 예외 발생함");
}
// 방법2) throws: 내가 지금 여기(method2)에서 처리 안 하겠다고, 메소드 호출한 곳(method1)으로 예외를 떠넘겨서/위임해서/던져서 처리하게 함
// 왠만하면 자신에게 발생한 예외는 자신이 처리하는 것이 좋음
// 떠넘기는 경우 예시: 내가 하기 귀찮거나.. 내가 할 필요가 없거나.. 예외들 모아서 예외처리하는 곳을 만들어둔 경우..
String str = br.readLine();
System.out.println("문자열의 길이 : " + str.length());
}
}
📗 소감
- 약 3주간의 Java 기본 문법 수업이 마무리되었다. 아직 Java의 정석 2권 내용은 거의 모르는데, 일단 Java 수업 끝이라니.. 2중/중첩 배열 연습도 못했는데.. DB 수업 후 11월 중순에 조금 더 알려주신다고 하니, 일단 객체 지향 개념 잊지 않도록 종종 연습해야겠다.
- 특히 오늘 배운 내용은 비교적 적은 예시로 빨리 지나갔는데, 개념이 생소할 뿐만 아니라 어디에 왜 사용하게 될지도 아직 잘 모르겠다. 그래서 더 어려운 느낌이다.
- 예외 처리도 중요하다고 들었는데, 충분히 예제를 보고 연습해서 익힐 시간 없이, 수업에서 너무 금방 지나갔다. 보충해서 공부하자!
📗 homework: 상속
(실습 파일 위치: 08 Inheritance > src > com > kh > hw > person)
'back-end dev > Java' 카테고리의 다른 글
[KH정보교육원] 21일차_미니팀프로젝트 (0) | 2021.11.09 |
---|---|
[KH정보교육원] 15일차_평가 및 미니팀프로젝트 (0) | 2021.11.07 |
[KH정보교육원] 13일차_다형성 (0) | 2021.11.07 |
[KH정보교육원] 12일차_상속 (0) | 2021.11.07 |
[KH정보교육원] 11일차_클래스, 객체 배열 (0) | 2021.11.07 |