* 18. 인스턴스 목록을 다루는 코드를 별도의 클래스로 분리
* GRASP 패턴
응집력을 높인다.
서로 관련된 기능을 묶어서 클래스 별로 더 전문적인 역할을 수행한다.
- UI MemberHanlder
- 기능 Memberlist (인스턴스 보관)
때문에 Cmd (Command Line Interface) 환경을 웹(Web) 환경으로 바꾸더라도
UI 기능의 Handler만 코드를 수정해주면 되기 때문에 재사용과 유지보수에 용이하다.
* 19. 범용 리스트 만들기
각각의 Member, Baord Handler 를 통해 각각의 List를 만들었다.
하지만 List의 구조가 비슷하기 때문에 범용 리스트를 만들어주는 것이 좋다.
* 다형적 변수
부모 클래스와 자식 클래스의 인스턴스와 객체 생성
A obj;
obj = new A(); True
A에는 A기능이 있다.
A obj;
obj = new B(); True
A에는 B기능이 있다.
A obj;
obj = new C(); True
A에는 C기능이 있다.
A obj;
obj = new D(); True
A에는 D기능이 있다.
D obj2;
obj = new A(); False
D에는 A기능이 없다.
D obj2;
obj = new B(); False
D에는 B기능이 없다.
D obj2;
obj = new C(); False
D에는 C기능이 없다.
D obj2;
obj = new D(); True
D에는 D기능이 있다.
* 기본 문법과 의미
Calculator2가 Calculator 을 사용하게하려면 상속 관계를 지정해주어야한다.
* 클래스와 상속관계 정리
* java.lang object 클래스
자바의 모든 클래스의 최상위 클래스로 Object가 존재한다.
즉, 자바의 모든 클래스는 Object의 자손이다.
또한 최상위 클래스 아래에는 수퍼 클래스가 존재한다.
ex) X ← X2 ← X2 ← X3 ← X4
static class X {
static class X2 extends X {
static class X3 extends X2 {
static class X4 extends X3 {
X는 최상위 클래스입니다.
X2는 X를 상속받은 자식 클래스입니다.
X3는 X2를 상속받은 자식 클래스입니다.
X4는 X3를 상속받은 자식 클래스입니다.
* Object의 메서드들
기존에는 Object에 있는 변수가 같은 지를 보는 것이 아니라
인스턴스 주소 자체가 같은 지를 비교하는 것이다.
때문에 수퍼 클래스의 equals를 재정의 한다.
* 오버라이딩 오버로딩
오버라이딩
상속 받은 클래스를 서브 클래스에 맞게 재정의
오버로딩
파라미터가 다르고 파라미터 갯수와 순서가 다르더라도 같은 기능을 하는 메소드에 대해서
같은 이름을 주어서 일관된 프로그래밍이 가능하게 해준다.
오버라이딩이란 ?
오버라이딩(overriding)은 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것을 말합니다.
오버라이딩은 다음 조건을 만족해야 합니다.
- 메서드 이름이 동일해야 합니다.
- 메서드 시그니처(이름과 매개변수의 타입, 개수, 순서)가 동일해야 합니다.
- 접근 제어자는 부모 클래스의 메서드보다 같거나 더 넓은 범위로 변경할 수 있습니다.
- 예외 타입은 부모 클래스의 메서드와 일치하거나, 부모 클래스의 메서드가 던지는
예외의 하위 타입을 선언할 수 있습니다. - 반환 타입은 일치해야 합니다. (자바 5부터는 반환 타입의 공변성을 허용합니다.)
따라서 오버라이딩은 부모 클래스의 메서드와 동일한 시그니처를 가져야 하며,
메서드 내부에서 추가적인 인스턴스 변수를 사용하거나 다른 동작을 정의할 수 있습니다.
인스턴스 변수의 추가나 다른 동작을 정의하는 것은 오버라이딩에 영향을 주지 않습니다.
오버라이딩된 메서드는 부모 클래스의 메서드와 동일한 시그니처를 유지하면서,
자식 클래스에서 부모 클래스의 동작을 재정의하여 사용할 수 있습니다.
따라서 오버라이딩은 메서드의 시그니처를 유지하면서 내부 동작을 변경하는 것이 가능하며,
추가적인 인스턴스 변수나 다른 동작을 정의하는 것은 허용됩니다.
이를 통해 자식 클래스는 부모 클래스의 동작을 확장하거나 수정할 수 있습니다.
오버라이딩 정리)
접근 범위가 같거나 커야 한다는 것은.
score 가 default 일때, score는 적어도 default 거나 범위가 더 큰 public 이어야 한다는 뜻이다.
또한 오버로딩과 다른 점은 상속 받은 메서드와 똑같은 시그니처 (메서드명, 파라미터 타입/개수/순서)로
메서드를 정의해야한다는 것이다. 대신 내부 인스턴스 변수를 추가하거나 다른 동작을 정의하는 것은
영향을 주지 않는다.
오버로딩은 같은 기능을 가진 메서드를 다른 타입/개수/순서를 가진 파라미터를
통해 재정의하는 것이다.
오버로딩이란 ?
같은 기능을 수행하는 메서드가 있다면 파라미터의 타입/갯수/순서가 다르더라도
같은 이름을 부여한다.
- 같은 기능을 수행하지만 다양한 타입의 매개변수를 처리해야 할 때: 예를 들어, add(int a, int b)와 add(double a, double b)라는 두 개의 메서드를 정의하여 정수와 실수의 덧셈을 처리할 수 있습니다.
- 메서드 이름이 직관적이고 일관성을 유지할 수 있을 때: 예를 들어, print(String message)와 print(int number)라는 두 개의 메서드를 정의하여 문자열과 숫자를 출력하는 메서드로 사용할 수 있습니다.
- 기본값이 있는 메서드를 제공할 때: 예를 들어, calculateArea(int length, int width)와 calculateArea(int length)라는 두 개의 메서드를 정의하여 직사각형의 넓이를 계산하는데 필요한 인자를 유연하게 처리할 수 있습니다. 두 번째 메서드는 가로와 세로 길이가 같은 정사각형의 경우에 사용될 수 있습니다.
코드예시)
public class Exam0420 {
static class X {
void m1() {
System.out.println("X의 m1()");
}
void m2() {
System.out.println("X의 m2()");
}
}
static class X2 extends X {
@Override
void m1() {
System.out.println("X2의 m1()");
}
}
static class X3 extends X2 {
@Override
void m2() {
System.out.println("X3의 m2()");
}
}
static class X4 extends X3 {
@Override
void m1() {
System.out.println("X4의 m1()");
}
void test() {
this.m1(); // X4의 m1() : this가 실제 가리키는 인스턴스 클래스를 기준으로 메서드를 찾아 올라 간다.
super.m1(); // X2의 m1() : test()가 소속된 클래스를 기준으로 수퍼 클래스부터 메서드를 찾아 올라간다.
this.m2(); // X3의 m2()
super.m2(); // X3의 m2()
// super.super.m1(); // 컴파일 오류! 이런 문법은 없다! 무협지 문법!
}
}
오버로딩 정리)
정리하자면, 오버로딩은 예를 들어 계산기 프로그램에서 수와 수를 더하는 기능을 수행하는
'plus'라는 메서드가 있을 때 a+b를 더하는 연산에서 a+b+c를 더하는 연산으로 수행할 경우
기존에는 메서드를 하나 더 만들어야하는 문제가 발생하고 개발자는 이러한 메서드의 이름을
기억해야하는 문제가 발생한다.
하지만 plus 라는 동일한 이름을 가진 메서드를 생성하고 파라미터의 유형이나 갯수 순서를 다르게 설정하여도
오버로딩을 통해 동일한 메서드 이름을 사용할 수 있으며 일관된 프로그래밍을 가능하게 해준다.