< 상속 >
❑ 상속이란?
상속은 OOP에서 아주아주 중요한 개념이다.
자바에서 상속은 말 그대로 부모 클래스가 자식 클래스에게 가지고 있는것을 물려주는 것을 말한다.
부모-자식 / 조상-자손 / parent class-child class 라고 표현하기도 한다.
하지만 상속의 의미를 생각했을 때 상위 클래스-하위 클래스라고 표현하는 것이 올바르다.
하위 클래스는 상위 클래스에서 속성과 기능을 모두 물려받아서 하위 클래스는 상위 클래스의 필드(field)와 메소드(method)를 쓸 수 있다.
🔎 그렇다면 상속은 언제 써야할까?
상속에서 상위 클래스는 하위 클래스를 포괄하는 일반적인 개념이고
하위 클래스는 상위 클래스보다 구체적인 개념이다.
상속은 이미 정의해놓은 클래스에 속성이나 기능을 추가해서 새로운 클래스를 만들려고 할 때 유용할 것이다.
이미 만들어놓은 클래스에 추가할 것만 새로 작성하면 되서 완전히 새로 작성하는 것보다 에너지가 적게 들 것이다.
그리고 상위 클래스를 통해서 아래에 여러 하위 클래스를 관리할 수 있기 때문에 유지보수하기 편할 것이다.
🌱 상속 개념 예시
포유류와 사람으로 예를 들어서 표현해보았다.
포유류는 사람, 고양이, 개보다 포괄적인 개념이고 사람, 고양이, 개는 포유류에 포함된다.
따라서 포유류가 상위 클래스이고 사람/고양이/개는 하위 클래스가 될 수 있다.
※ 상속을 표현할 때 화살표는 항상 하위 클래스에서 상위 클래스 쪽으로 향하게 그린다.
여기서 또 사람은 프로그래머/요리사/화가보다 일반적인 개념이다.
따라서 사람 클래스는 이번엔 프로그래머, 요리사, 화가 클래스의 상위 클래스가 될 수 있다.
이렇게 상속은 누군가의 하위 클래스이면서 동시에 누군가의 상위 클래스가 될 수 있다.
자바에서 상속을 구현할 때는 extends라는 예약어를 사용한다.
class child extends parent {
}
하위 클래스의 이름 옆에 'extends 상위클래스' 를 작성하면 상위-하위 클래스 관계가 된다.
🔔 참고) 다중 상속
다중 상속은 한 클래스가 여러 클래스에서 상속받는 것이다.
객체지향 언어인 C++에서는 다중 상속이 가능하지만 자바에서는 지원하지 않는다.
자바에서는 하위 클래스는 단 하나의 상위 클래스만 가질 수 있다. (extends 뒤엔 하나의 클래스만 올수 있다.)
여러 클래스에서 상속받으면 다양한 기능을 상속받을 수 있지만 모호성의 문제가 있다.
객체 지향에서 다중상속으로 인한 대표적인 문제가 다이아몬드 문제이다.
C++에서는 문법적으로 이를 해결했지만 자바는 모호함을 없애고 다중 상속을 사용하지 않는 것을 택한 것이다.
하지만 자바에서도 다형성이나 인터페이스라는 개념들로 다중 상속과 비슷한 효과를 낼 수 있다.
❑ 포함 관계
자바의 클래스들은 서로 관계적이다.
그렇다면 모든 관계가 상속일까? ❌
클래스간의 관계에는 상속도 있지만 '포함' 관계도 있다.
포함은 클래스 내에서 사용하기 위해서 정의한 클래스 관계이다.
public class Student {
Subject math = new subject("math");
}
public class Subject {
String name;
Subject(String name) {
this.name = name;
}
}
예를 들어서 학생 클래스와 과목 클래스가 있을 때 과목 객체들은 모두 학생 클래스에 속하게 된다.
이럴 때 상속으로 만들면 어떻게 될까?
학생 클래스의 속성과 메소드는 과목 클래스에서 재사용하기 어렵다.
하지만 학생 클래스에서 과목 클래스를 만들어서 사용한다.
이럴 때는 상속보다는 포함 관계로 만드는 것이 좋다.
※ 상속은 '일반적인 개념-구체적인 개념' 다시말해
'IS-A 관계' (is a relationship) 에서 사용하는 것이 좋다.
'~(하위클래스)는 ~(상위클래스)이다' 로 표현했을 때 어색하지 않다면 상속으로 쓰면 된다.
- 예시 -
학생은 사람이다.
강아지는 동물이다.
카카오톡은 앱이다.
※ 포함은 'HAS-A 관계(has a relationship)' 에서 사용하는게 좋다.
'~는 ~를 가지고 있다.' 로 표현했을 때 어색하지 않다면 포함으로 쓰면 된다.
- 예시 -
컴퓨터는 모니터를 가지고 있다.
플레이어는 레벨을 가지고 있다.
❑ 메소드 오버라이딩 ( Method Overriding)
메서드 오버라이딩이란?
상위 클래스에서 정의된 메소드를 하위 클래스에서 재정의 하는 것이다.
상위 클래스에서 정의한 메소드를 하위 클래스마다 다르게 사용할 때가 있다.
오버라이딩 된 메소드라는 것을 컴파일러에 알려주기 위해서 재정의할 메소드 위에 '@Override'를 작성해준다.
public class Person {
void walk() {
System.out.println("걷습니다.");
}
}
class Dancer extends Person {
@Override
void walk() {
System.out.println("춤추면서 걷습니다.");
}
}
⚠️ 오버라이딩 조건
✅ 반환형, 메소드 이름, 매개변수 개수, 매개변수 자료형이 반드시 같아야함
✅ 접근 제어자의 범위가 상위 클래스의 메소드보다 같거나 넓어야 함
✅ 예외는 상위 클래스의 메소드보다 많이 선언할 수 없음
➤ 조건을 지키지 않으면 자바 컴파일러가 재정의한 메소드를 기존의 메소드와 다른 메소드로 인식!
❑ super
상속에서 쓰는 super의 역할은 this 와 비슷하다.
super는 하위클래스에서 상위 클래스를 부르는 예약어다.
super 와 super()는 this처럼 역할이 다르다.
super
하위클래스에서 상위클래스를 부를 때 사용한다.
super()
하위클래스의 생성자에서 상위클래스의 생성자를 부를 때 사용한다.
생성자의 첫번째 줄에 작성해야 한다.
하위클래스 생성자에 작성하지 않아도 자동으로 호출한다.
❑ 최상위 클래스 Object
자바에서는 'Object'라는 말은 객체라는 의미이기도 하지만 최상위 클래스를 의미한다.
모든 클래스는 Object 밑에 하위 계층에 존재한다.
만약에 어떤 클래스를 만들었는데 extends를 작성하지 않으면 컴파일러가 자동으로 'extends Object'를 작성한다.
따라서 모든 클래스는 Object에 정의된 메소드들을 사용할 수 있다.
Object의 대표적인 메소드
메소드 | 설명 |
toString() | 객체를 문자열로 표현하여 반환, 재정의하여 객체에 대한 설명이나 특정 멤버 변수 값을 반환함 |
boolean equals(Object obj) | 두 인스턴스가 동일한지 여부를 반환, 재정의하여 논리적으로 동일한 인스턴스임을 정의할 수 있음 |
in hashCode() | 객체의 해시코드 값을 반환(위치정보) |
Object clone() | 객체를 복제하여 동일한 멤버 변수 값을 가진 새로운 인스턴스를 생성함 |
Class getClass() | 현재 객체가 참조하고 있는 클래스를 반환함 |
void finalize() | 인스턴스가 힙 메모리에서 제거될 때 가비지 컬렉터에 의해 호출되는 메소드, 네트워크 연결 해제, 열려 있는 파일 스트림 해제 등을 구현 |
void wait() | 멀티스레드 프로그램에서 사용하는 메소드, 스레드를 '기다리는 상태'로 만듦 |
void notify() | wait() 메소드에 의해 기다리고 있는 스레드를 실행 가능한 상태로 가져옴 |
'TIL(Today I Learned)' 카테고리의 다른 글
5/16 (월) 자바 코딩과 여러가지 오류,, (0) | 2022.05.16 |
---|---|
5/13 (금) 자바 다형성 (0) | 2022.05.13 |
5/11 (수) 객체지향 프로그래밍 기초2 (생성자) (0) | 2022.05.11 |
5/10 (화) 객체지향 프로그래밍 기초 (0) | 2022.05.11 |
5/9 (월) 자바 배열 / 계산기 만들기 (0) | 2022.05.09 |