[Java] 객체 지향 프로그래밍 - 상속(Inheritance)

2025. 11. 23. 19:52·Language/Java
반응형

 

1️⃣ 상속 (Inheritance)

  • 기존(상위) 클래스의 자신(멤버)을 자식(하위) 클래스에서 재사용하기 위한 것
    • 상위 클래스의 생성자와 초기화 블록은 상속하지 않는다
  • 상위 클래스의 멤버를 물려 받기 때문에 코드의 절감
    • 상위 클래스의 코드를 변경하면 모든 하위 클래스들에게도 적용 → 유지보수성 향상
  • 상속의 적용
    • extends 키워드 사용

 

조상 클래스(= 상위 클래스, 슈퍼 클래스) → 자식 클래스(= 하위 클래스, 서브 클래스)

 

🔹 Object 클래스

모든 클래스의 조상 클래스

  • 별도의 extends 선언이 없는 클래스들은 extends Object가 생략됨
  • 모든 클래스에는 Object 클래스에 정의된 메서드가 있음

 

🔹 다양한 상속 관계

  • 상속의 관계는 is a (kind of) 관계라고 함
    • ex) Person is a Object, SpiderMan is a Person

 

🔹 단일 상속 (Single Inheritance)

  • 다중 상속의 경우 여러 클래스의 기능을 물려받을 수 있으나 관계가 매우 복잡해짐
    • 동일한 이름의 메서드가 두 상위 클래스에게 모두 있다면 하위 클래스는 어떤 메서드 써야 되냐구..ㅜ 그니까 안돼
  • 자바는 단일 상속만 지원
    • 대신 interface와 포함 관계(has a)로 단점 극복

 

🔹 포함 관계

  • 상속 이외에 클래스를 재활용하는 방법
    • 2개 이상의 클래스에서 특성을 가져올 때 하나는 상속, 나머지는 멤버 변수로 처리
    • 포함 관계의 UML 표현: 실선 화살표
    • Spider(멤버 변수)의 코드를 수정하면 SpiderMan에도 반영되므로 유지 보수성 확보
  • 어떤 클래스를 상속 받고 어떤 클래스를 포함해야 하지?
    • 문법적인 문제 x 프로그램의 관점 문제 o
    • 상속: is a 관계 성립하니? (상속은 한 번만!!)
    • 포함: has a 관계 성립하니?

 


 

2️⃣ 메서드 재정의

🔹 메서드 오버라이딩 (overriding)

조상 클래스에 정의된 메서드를 자식 클래스에서 적합하게 수정하는 것

  • overwrite로 외우자! 덮어쓰기!
    • 오버로딩은 여러 개를 만드는 거고, 오버라이딩은 덮어써서 이전 것들은 숨어있음

 

🔹 오버라이딩의 조건

  • 메서드 이름이 같아야 한다
  • 매개 변수의 개수, 타입, 순서가 같아야 한다
  • 리턴 타입이 같아야 한다
  • 접근 제한자는 부모보다 범위가 넓거나 같아야 한다
  • 조상보다 더 큰 예외를 던질 수 없다

 

🔹 super 키워드

  • `this`를 통해 멤버에 접근했듯이 super를 통해 조상 클래스 멤버 접근
    • `super.`을 이용해 조상의 메서드 호출로 조상의 코드 재사용
void jump() {
		if (isSpider) {
			spider.jump();
		} else {
			super.jump();
		}
	}
  • 변수의 scope
    • 사용된 위치에서 점점 확장해가며 처음 만난 선언부에 연결됨
    • method 내부 → 해당 클래스 멤버 변수 → 조상 클래스 멤버 변수
  • `this()`가 해당 클래스의 다른 생성자를 호출하듯 `super()`는 조상 클래스의 생성자 호출
    • 조상 클래스에 선언된 멤버들은 조상 클래스의 생성자에서 초기화가 이뤄지므로 이를 재활용
    • 자식 클래스에 선언된 멤버들만 자식 클래스 생성자에서 초기화
  • `super()`는 자식 클래스 생성자의 맨 첫 줄에서만 호출 가능
    • 즉 생성자의 첫 줄에만 this() 또는 super()가 올 수 있다.
    • this()와 super()를 같이 쓸 수 없음
  • 명시적으로 `this()` 또는 `super()`를 호출하지 않는 경우 컴파일러가 `super()` 삽입
    • 결론적으로 맨 상위의 Object까지 객체가 다 만들어지는 구조

 

🔹 Annotation

  • 사전적 의미: 주석
  • 컴파일러, JVM, 프레임워크 등이 보는 주석
  • 소스코드에 메타 데이터를 삽입하는 형태
    • 소스코드에 붙여 놓은 라벨
    • 코드에 대한 정보 추가 → 소스코드의 구조 변경, 환경 설정 정보 추가 등의 작업 진행
  • 예시
    • @Deprecated: 컴파일러에게 해당 메서드가 deprecated(지원 종료 예정)되었다고 알려줌
    • @Override: 컴파일러에게 해당 메서드는 override한 메서드임을 알려줌
    • @SuppressWarnings: 컴파일러에게 사소한 warning의 경우 신경 쓰지 말라고 알려줌

 


 

3️⃣ package & import

  • pc의 많은 파일 관리 → 폴더 이용
    • 유사한 목적의 파일을 기준으로 작성
    • 이름은 의미 있는 이름으로, 계층적 접근
  • 프로그램의 많은 클래스 → 패키지 이용
    • 패키지의 이름은 의미 있는 이름으로 만들고 .을 통해 계층적 접근
    • 물리적으로 패키지는 클래스 파일을 담고 있는 디렉터리
    • package name + class name으로 클래스 구분 → fully qualified name
  • package 선언
    • `package package_name;`
    • 주석, 공백을 제외한 첫 번째 문장에 하나의 패키지만 선언
    • 모든 클래스는 반드시 하나의 패키지에 속한다
      • 생략 시 default package에 속하는데 권장하지 않음

 

🔹 package

  • 일반적인 package naming 룰
    • 소속.프로젝트. 용도
      • ex) com.ssafy(회사의 identity).hrm(project).common(용도)

 

🔹 import

  • 다른 패키지에 선언된 클래스를 사용하기 위한 키워드
    • 패키지와 클래스 선언 사이에 위치
    • 패키지와 달리 여러 번 선언 가능
  • 선언 방법
    • import 패키지명.클래스명;
    • import 패키지명.*;
      • 하위 패키지까지 import 하지는 않음
  • import한 package의 클래스 이름이 동일하여 명확히 구분해야 할 때
    • 클래스 이름 앞에 전체 패키지명을 입력
      • ex) `java.util.List list = new java.util.ArrayList();`
  • default import package: `java.lang.*;`

 

4️⃣ 제한자 (modifier)

  • 클래스, 변수, 메서드 선언부에 함께 사용되어 부가적인 의미 부여
  • 종류
    • 접근 제한자: public, protected, (default = package), private
    • 그 외 제한자
      • static: 클래스 레벨의 요소 설정
      • final: 요소를 더 이상 수정할 수 없게 함
      • abstract: 추상 메서드 및 추상 클래스 작성
      • synchronized: 멀티스레드에서의 동기화 처리
      • …
  • 하나의 대상에 여러 제한자를 조합 가능하나 접근 제한자는 하나만 사용 가능
  • 순서는 무관 (일반적으로 접근 제한자가 맨 앞)

 

🔹 final

  • 마지막, 더 이상 바뀔 수 없음
  • final class: 더 이상 확장할 수 없음 - 상속 금지 → 오버라이드 방지
    • 왜 상속 못하게 막음? 이미 완벽하니까 건들지 마셈
  • final method: 더 이상 재정의할 수 없음 - overriding 금지
  • final variable: 더 이상 값을 바꿀 수 없음(상수)
  • Blank final: 값이 할당되지 않은 멤버 변수
    • final 멤버 변수에 초기 값이 할당되어 버리면 모든 객체는 같은 값을 사용해야 함
    • 객체가 생성되면 값을 변경할 기회가 없기 때문에 생성자에서 1회 초기화 가능
  • static final
    • 단지 final만 있으면 객체마다 갖는 값으로 공용성이 없음
    • 진정한 상수는 객체와 무관하게 모두가 공용하는 값(Math.PI, Math.E, ..)
반응형
'Language/Java' 카테고리의 다른 글
  • [Java] 객체 지향 프로그래밍 - 다형성(Polymorphism)
  • [Java] 객체 지향 프로그래밍 - 추상화(Abstraction)
  • [Java] 자바 기본 문법 총정리
  • [Java] 클래스와 데이터
올콩
올콩
콩 심은 데 콩 난다
  • 올콩
    콩스토리
    올콩
  • 전체
    오늘
    어제
    • 분류 전체보기 (213) N
      • SSAFY (10)
      • Algorithm (122)
        • 이론 (6)
        • 백준 (BOJ) (114)
        • 프로그래머스 (1)
        • 코드트리 (1)
      • Trouble Shooting (11)
      • Frontend (7)
      • React (17)
      • Next.js (5)
      • Vue (4)
      • Node.js (2)
      • HTML (9)
      • DevOps (4)
        • Git (4)
      • Language (13) N
        • JavaScript (0)
        • Java (13) N
      • Embedded (1)
      • CS (5)
        • Network (1)
        • Blockchain (4)
      • 자격증 (2)
      • 기타 (1)
        • Tistory (1)
  • 블로그 메뉴

    • GitHub
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    강의
    React
    파이썬
    Algorithm
    Next.js
    백트래킹
    중복순열
    Java
    티스토리챌린지
    오블완
    백준
    수학
    우선순위큐
    Error
    그리디
    bfs
    DP
    html5
    SSAFYcial
    브루트포스
    구현
    블록체인
    Heap
    dfs
    순열
    싸피
    힙
    SSAFY
    재귀
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
올콩
[Java] 객체 지향 프로그래밍 - 상속(Inheritance)
상단으로

티스토리툴바