STUDY/Java
[Java] 상속 (Inheritance)
ofijwe
2024. 10. 20. 22:05
반응형
📒 상속
1️⃣ 상속 (Inheritance: OOP Is PIE)
- 기존(상위) 클래스의 자산(멤버)을 자식(하위) 클래스에서 재사용하기 위한 것
- 상위 클래스의 생성자와 초기화 블록은 상속 X
- 상위 클래스의 멤버를 물려 받기 때문에 코드 절감
- 상위 클래스 코드 변경 시 하위 클래스에도 적용 → 유지 보수성 향상
- 상속은 extends 키워드를 사용해 적용
2️⃣ Object 클래스
- 모든 클래스의 조상 클래스
- 별도의 extends 선언이 없는 클래스는 extends Object 가 생략됨.
- 모든 클래스에는 Object 클래스에 정의된 메서드 O
3️⃣ 단일 상속 (Single Inheritance)
- Java는 단일 상속만 지원
- interface와 포함 관계(has a)로 단점 극복
- 다중 상속 → 여러 클래스 기능 물려받을 수 O / but, 관계 복잡
4️⃣ 포함 관계
- 상속 이외에 클래스를 재활용 하는 방법
- 2개 이상의 클래스에서 특성을 가져올 때 하나는 상속, 나머지는 멤버 변수로 처리
- 포함 관계 UML 표현 → 실선 화살표
- 유지 보수성 확보
- 상속을 할 것인지 포함을 할 것인지 중요
- 어떤 클래스를 상속 받고 어떤 클래스를 포함해야 하는지 중요 → 프로젝트 관점 문제
- 상속: is a 관계가 성립하는지
- 포함: has a 관계가 성립하는지
📒 메서드 재정의
1️⃣ 메서드 오버라이딩(overriding)
- 조상 클래스에 정의된 메서드를 자식 클래스에서 적합하게 수정하는 것
- 오버로딩 → 계속 적재하는 것 / 오버라이딩 → 계속 덮어쓰는 것
- 조건 → 조상부와 동일
- 메서드 이름 동일 (조상이 물려준 메서드와)
- 매개 변수 개수, 타입, 순서 동일
- 리턴 타입 동일
- 접근 제한자는 부모 보다 범위가 넓거나 동일
- 조상보다 더 큰 예외를 던질 수 X
2️⃣ super 키워드
- 나의 조상
- this로 멤버에 접근했듯이 super를 통해 조상 클래스 멤버 접근
- super. 을 이용해 조상의 메서드 호출로 조상의 코드 재사용
- 변수의 scope
- 사용된 위치에서 점점 확장해가며 처음 만난 선언부에 연결됨
- method 내부 → 해당 클래스 멤버 변수 → 조상 클래스 멤버 변수
- super()는 조상 클래스의 생성자 호출
- 조상 클래스에 선언된 멤버들은 조상 클래스의 생성자에서 초기화가 이뤄지므로 이를 재활용
- 자식 클래스에 선언된 멤버들만 자식 클래스 생성자에서 초기화
- super()는 자식 클래스 생성자의 맨 첫 줄에서만 호출 가능
- 생성자의 첫 줄에만 this() 또는 super()가 올 수 있음.
- 명시적으로 this() 또는 super()를 호출하지 않는 경우 컴파일러가 super() 삽입
- 맨 상위 Object까지 객체가 다 만들어지는 구조
class Person { String name; Person(String name) { this.name = name; } }
- 생성자 호출과 객체 생성의 단계
class Person { String name; Person(String name) { this.name = name; } } public class SpiderMan extends Person { Spider spider = new Spider(); boolean isSpider; SpiderMan(String name, Spider spider, boolean isSpider) { super(name); this.spider = spider; this.isSpider = isSpider; } SpiderMans(String name) { this(name, new Spider(), true); } public static void main(String[] args) { Spider sman = new SpiderMans("피터 파커"); } }
3️⃣ Annotation
- 사전적 의미 → 주석 / 컴파일러, JVM, 프레임워크 등이 보는 주석
- 소스코드에 메타 데이터를 삽입하는 형태
- 소스 코드에 붙여 놓은 라벨
- 코드에 대한 정보 추가 → 소스 코드의 구조 변경, 환경 설정 정보 추가 등의 작업 진행
- 기본 Annotation
- @Deprecated : 컴파일러에게 해당 메서드가 deprecated 되었다고 알려줌
- @Override : 컴파일러에게 해당 메서드는 override한 메서드 임을 알려줌 (반드시 super class에 선언되어 있는 메서드여야 함)
- @SuppressWarnings : 컴파일러에게 사소한 warning의 경우 신경 쓰지 말라고 알려줌
📒 Package & import
1️⃣ Package
- PC의 많은 파일 관리 → 폴더 이용
- 유사한 목적의 파일 기준
- 의미있는 이름으로 계층적 접근
- 프로그램의 많은 클래스 → 패키지 이용
- 의미있는 이름으로 만들고, . 을 통해 계층적 접근
- 물리적으로 패키지는 클래스 파일을 담고 있는 디렉터리
- package name + class name으로 클래스 구분 → fully qualified name
- package 선언
- package package_name;
- 첫 문장에 하나의 패키지만 선언
- 모든 클래스는 반드시 하나의 패키지에 속함 → 생략 시 default package에 속함 / but, 가급적 사용 X
- 일반적인 package naming 툴
- 소속, 프로젝트, 용도
2️⃣ import
- 다른 패키지에 선언된 클래스를 사용하기 위한 키워드
- 패키지와 클래스 선언 사이에 위치
- 패키지와 달리 여러 번 선언 가능
- 선언 방법
- import 패키지명.클래스명;
- import 패키지명.*; → 하위 패키지까지 import 하지 X
- import한 package의 클래스 이름이 동일하여 명확히 구분해야 할 때 → 클래스 이름 앞에 패키지 명 입력
- default import package
- java.lang.*;
3️⃣ static import
- static member에 대한 import
- 자주 사용되는 static member를 import 하여 static member 이름만으로 접근
📒 제한자
1️⃣ 제한자
- 클래스, 변수, 메서드 선언부에 함께 사용되어 부가적인 의미 부여
- 종류
- 접근 제한자
- public
- protected
- (default = package)
- private
- 그 외 제한자
- static : 클래스 레벨 요소 설정
- final : 요소를 더 이상 수정할 수 없게 함
- abstract : 추상 메서드 및 추상 클래스 작성
- synchoronized : 멀티스레드에서의 동기화 처리
- 접근 제한자
- 하나의 대상에 여러 제한자 조합 가능 / but, 접근 제한자는 하나만 사용 가능
- 순서 무관 → but, 일반적으로 접근 제한자를 맨 앞에 둠
2️⃣ final
- 마지막, 더 이상 바뀔 수 없음
- final class
- 더 이상 확장할 수 X
- 상속 금지 → 오버라이드 방지
- final method
- 더 이상 재정의 할 수 X
- overriding 금지
- final variable
- 더 이상 값 변경할 수 X
- Blank final
- 값이 할당되지 않은 멤버 변수
- final 멤버 변수에 초기 값이 할당되어버리면 모든 객체는 같은 값을 사용해야 함.
- 객체가 생성되면 갑을 변경할 기회 X → 반드시 생성자에서 1회 초기화 가능
- 생성자에서 초기화를 가제하는 역할
- static final
- 단지 final만 있으면 객체마다 갖는 값으로 공용성이 없음
- 진정한 상수는 객체와 무고나하게 모두가 공용하는 값
3️⃣ 접근 제한자(Access modifier)
- 멤버 등에 사용되며 해당 요소를 외부에서 사용할 수 있는지 설정
- method override 조건 확인
- 부모의 제한자 범위와 같거나 넓은 범위로만 사용 가능
- Private < Default < Protected < Public
- 접근 제한자 종류 & 차이
4️⃣ Sealed class
- 봉인된 클래스로 특정 클래스에게만 상속 가능
- 상속 계층 내에서 엄격한 제어
- 프로그램 구조 명확하게 유지, 의도치 않은 상속으로 인한 복잡성 및 혼란 방지
- 명확한 역할과 직무 분류가 중요한 개념에 주로 사용
- 작성법
- 클래스에 sealed 키워드 사용 → 상속을 허락하는 클래스를 permits 뒤에 나열
- sealed가 선언된 클래스는 permits 반드시 필요
- 구현 클래스에 필요한 키워드
- sealed : 봉인된 클래스, 추가적으로 permits로 하위 클래스 나열 필요
- final : 더 이상 상속 받을 수 없는 클래스
- non-sealed : 봉인이 해제된 클래스 → 자유롭게 상속 가능
- 클래스에 sealed 키워드 사용 → 상속을 허락하는 클래스를 permits 뒤에 나열
반응형