3 분 소요

상속

개념

  • 부모 클래스(상위 클래스)의 멤버를 자식 클래스(하위 클래스)에 물려주는 것
  • 이미 잘 개발된 클래스를 재사용해서 새로운 클래스 생성 ⇒ 코드 중복 줄여줌
  • 부모 클래스에서 private 접근 제한자를 갖는 필드와 메소드는 상속 대상에서 제외
  • 부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외
  • 클래스 수정 최소화, 유지보수 시간 최소화

클래스 상속

  • 자식 클래스를 선언하고 extends 뒤에 상속 받을 부모 클래스 명시

      class 자식클래스 extends 부모클래스 {
      }
    
  • 자바는 다중상속을 허용하지 않음

    • 여러 개의 부모 클래스를 상속할 수 없음

부모 생성자 호출

  • 자식 객체를 생성하면 부모 객체가 먼저 생성되고 자식 객체가 그 다음에 생성
  • 모든 객체는 클래스의 생성자를 호출해야만 생성됨
    • super() : 생성자가 명시적으로 선언되지 않았을 때 부모의 기본 생성자 호출. 컴파일러가 생성
  • 부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 있다면 자식 생성자에서 반드시 부모 생성자 호출을 위해 super(매개값) 명시적으로 호출
    • 반드시 자식 생성자 첫 줄에 위치

메소드 재정의

오버라이딩

  • 상속된 메소드의 내용이 자식 클래스에 맞지 않을 경우, 자식 클래스에서 동일한 메소드 재정의
  • 메소드가 오버라이딩 되면 부모 객체의 메소드 숨겨져 자식 객체에서 메소드 호출하면 오버라이딩 된 자식 메소드 호출
  • 메소드 오버라이딩 규칙
    • 부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 리스트) 가져야 함
    • 접근 제한을 더 강하게 오버라이딩할 수 없음
    • 새로운 예외(Exception)를 throws할 수 없음

부모 메소드 호출(super)

  • 자식 클래스 내부에서 오버라이딩된 부모 클래스의 메소드를 호출해야 하는 상황 ⇒ super 키워드로 부모 메소드 호출

final 클래스와 final 메소드

상속할 수 없는 final 클래스

  • final 키워드는 최종적이라는 뜻 ⇒ 상속할 수 없음
  • 자식 클래스 만들 수 없음

오버라이딩할 수 없는 final 메소드

  • 부모 클래스에 선언된 final 메소드를 자식 클래스에서 오버라이딩 불가

protected 접근 제한자

  • public과 default 접근 제한의 중간
  • 같은 패키지에서는 default 처럼 접근 제한이 없지만, 다른 패키지에서는 자식 클래스만 접근 허용
  • 필드, 생성자, 메소드 선언에 사용

타입 변환과 다형성

다형성

  • 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질
  • 하나의 타입에 여러 객체를 대입해서 다양한 기능을 이용할 수 있도록 함
  • 다형성 위해 부모 클래스로 타입 변환 허용 ⇒ 객체의 부품화

자동 타입 변환

  • 프로그램 실행 도중 자동으로 타입 변환
  • 자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있음
  • 바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이면 자동 타입 변환이 일어날 수 있음
  • 부모 타입으로 자동 타입 변환 ⇒ 부모 클래스에서 선언된 필드와 메소드만 접근 가능
    • 메소드가 자식 클래스에서 오버라이딩 되었다면 자식 클래스의 메소드가 대신 호출 ⇒ 다형성

필드의 다형성

  • 필드 값을 다양화함으로써 실행 결과가 다르게 나오도록 구현
    • 필드 타입은 변함 없지만 실행 도중에 어떤 객체를 필드로 저장하느냐에 따라 실행 결과 달라질 수 있음

하나의 배열로 객체 관리

class Car {
	Tire frontLeftTire = new Tire("앞왼쪽", 6);
	Tire frontRightTire = new Tire("앞오른쪽", 2);
	Tire backLeftTire = new Tire("뒤왼쪽", 3);
	Tire backRightTire = new Tire("뒤오른쪽", 4);
}
class Car {
	Tire[] tires = {
		new Tire("앞왼쪽", 6)),
		new Tire("앞오른쪽", 2),
		new Tire("뒤왼쪽", 3),
		new Tire("뒤오른쪽", 4)
	}
}
  • tires[1] = new KumhoTire("앞오른쪽", 13);
    • tires 배열의 각 항목은 Tire 타입이므로 자식 객체인 KumhoTire를 대입하면 자동 타입 변환이 발생하기 때문에 아무런 문제 없음

매개 변수의 다형성

  • 자동 타입 변환은 필드의 값을 대입할 때에도 발생하지만 메소드 호출할 때 많이 발생
  • 메소드 호출 시 매개 변수의 타입과 동일한 매개값을 지정하는 것이 정석
    • 매개값을 다양화하기 위해 매개 변수에 자식 타입 객체를 지정할 수도 있음
  • 매개 변수의 타입이 클래스일 경우, 해당 클래스의 객체 뿐만 아니라 자식 객체까지 매개값으로 사용할 수 있음

강제 타입 변환

  • 부모 타입을 자식 타입으로 변환하는 것
    • 모든 부모 타입을 자식 클래스 타입으로 강제 변환할 수 있는 것은 아님
    • 자식 타입이 부모 타입으로 자동 변환한 후, 다시 자식 타입으로 변환할 때 강제 타입 변환 사용
    • 자식 타입이 부모 타입으로 자동 변환하면, 부모 타입에 선언된 필드와 메소드만 사용 가능
    • 자식 타입에 선언된 필드와 메소드를 꼭 사용해야 한다면 강제 타입 변환으로 자식 타입으로 변환 후 자식 타입의 필드와 메소드 사용

객체 타입 확인

  • instanceof 연산자로 어떤 객체가 어떤 클래스의 인스턴스인지 확인

      boolean result = 객체 instanceof 타입
        
      // 객체가 해당 타입으로 생성됐으면 true, 아니면 false 반환
    

추상 클래스

개념

  • 클래스들의 공통적인 특성을 추출해서 선언한 클래스
  • 추상 클래스(부모)와 실체 클래스(자식)는 상속의 관계
  • 추상 클래스는 객체를 직접 생성해서 사용할 수 없음 ⇒ new 연산자를 사용해서 인스턴스 생성하지 못함
  • extends 뒤에만 올 수 있는 클래스

용도

  • 실체 클래스들의 공통된 필드와 메소드의 이름을 통일
  • 실체 클래스를 작성할 때 시간 절약

선언

public abstract class 클래스 {
	// 필드
	// 생성자
	// 메소드
}
  • abstract 키워드 사용
  • 상속을 통해 자식 클래스를 만들 수 있음
  • 일반 클래스와 마찬가지로 필드, 생성자, 메소드 선언

추상 메소드와 오버라이딩

  • 추상 메소드는 추상 클래스에서만 선언 가능
  • 메소드 선언부만 있고 실행 내용인 중괄호가 없는 메소드
    • 하위 메소드가 반드시 실행 내용을 채우도록 강요하고 싶은 메소드가 있을 경우 사용
    • 자식 클래스는 반드시 추상 메소드를 재정의(오버라이딩) 해서 실행 내용 작성해야 함