상속과 다형성

JH·2022년 11월 27일
0

2022-Java-Study

목록 보기
8/10

상속

클래스를 정의할 때 이미 구현된 클래스를 상속받아서 속성이나 기능이 확장되는 클래스를 구현하는 것

  • 상위 클래스는 일반적인 의미를 가진다.
  • 하위 클래스는 구체적인 의미를 가진다.
  • 자바는 하나의 상속만 가능하다.
class B extends A {
	
}

접근 제한자 가시성

외부 클래스하위 클래스동일 패키지내부 클래스
publicOOOO
protectedXOOO
defaultXXOO
privateXXXO

상속에서 클래스 생성 과정

  1. 상위 클래스 생성 후 하위 클래스 생성
  2. 상위 클래스 생성자 호출 후 하위 클래스 생성자 호출
  3. 생성자가 없는 경우. 상위 클래스 기본 생성자 호출을 위해 super()을 넣어줌

❗️ 반드시 상위-하위 생성자를 호출해야하므로 없으면 명시적으로 호출한다.

상속에서 메모리 상태

상위 클래스의 인스턴스가 먼저 생성되고, 하위 클래스의 인스턴스가 생성된다.

접근이 안될 뿐, super.private프로퍼티하면 생성이 된 것을 알 수 있다.

super 예약어

this가 자신의 인스턴스 주소를 갖는 것처럼, super는 하위 클래스가 상위 클래스에 대한 주소를 갖는다.

업캐스팅

상위 클래스로의 묵시적 형 변환.
하위 클래스는 상위 클래스의 타입을 내포하고 있어서 상위 클래스로 선언하고 하위 클래스 인스턴스를 생성할 수 있다.

Human lee = new Woman();

매서드 오버라이딩

상위 클래스에 정의된 메서드에 수정이나 추가 기능이 필요한 경우 같은 이름과 매개변수로 하위 클래스에서 재정의한다.

가상 메서드

프로그램에서 어떤 객체의 변수나 메서드의 참조는 그 타입에 따라 이루어진다.
가상 메서드는 타입과 상관없이 실제 생성된 인스턴스의 메서드가 호출되는 원리이다.

Human lee = new Woman();

lee의 타입은 Human이지만, 실제 생성된 인스턴스인 Woman 클래스의 (부모와 기능이 같은)메서드가 호출된다.

다형성

하나의 코드가 여러 가지 자료형으로 구현되어 실행되는 것

class Animal {
    public void move(){
        System.out.println("동물이 움직인다.");
    }
}

class Human extends Animal {
    public void move() {
        System.out.println("사람이 걷는다.");
    }
}

class Tiger extends Animal {
    public void move() {
        System.out.println("호랑이가 움직인다.");
    }
}

public class AnimalTest {
    public static void main(String[] args) {
        AnimalTest test = new AnimalTest();
        test.moveAnimal(new Human());
        test.moveAnimal(new Tiger());
        // 사람이 걷는다.
		// 호랑이가 움직인다.
    }

    public void moveAnimal(Animal a){
        a.move();
    }
}
  • 하나의 클래스(Animal)를 상속받은 여러 클래스(Human, Tiger)가 있는 경우
  • 각 클래스마다 같은 이름의 다른 메서드(move)를 재정의
  • 상위 클래스 타입으로 선언된 하나의 변수가 여러 인스턴스에 대입되어 다양한 구현이 가능 (a.move();)

상속은 언제 사용?

공통적인 요소는 모으고 상속받아 필요한 특성과 메서드를 구현하는 방법

IS-A 관계

일반적인 개념과 구체적인 개념의 관계

HAS-A 관계

한 클래스가 다른 클래스를 소유한 관계 (코드 재사용)

다운 캐스팅 (instanceof)

하위 클래스가 상위 클래스로 형 변환 되는 것은 묵시적으로 이루어지지만 다시 돌아가려면 명시적으로 다운 캐스팅을 해야한다.

이때 원래 인스턴스의 타입을 체크하는 예약어가 instanceof이다.

public void moveAnimal(Animal a){
	a.move();

	if (a instanceof Human) {
    	Human human = (Human) a;
        human.readBook();
    }
    else if (a instanceof Tiger) {
    	Tiger tiger = (Tiger) a;
    	tiger.hunting();
    }
}
profile
매일 한 문제씩 풀기

0개의 댓글