[2024-04-26] 상속과 동적 바인딩

XingXi·2024년 4월 26일
0

기록

목록 보기
25/33
post-thumbnail

글을 쓴 계기

어쩌다가 컴파일 타임 시점에 실행 코드가 결정된다는 글을 봤다.
정적 바인딩에 대한 내용이다. 오랜만에 본 내용을 정리해 보자라는 생각이 들었다.


왜 Extends 일까

class Warrior extends Adventure{
}
  • 좋지 않은 기억력을 살려서 왜 Extends 라는 말이 상속으로 쓰이는지 적어보았다.

자바에서 상속을 사용할 때 위 처럼 extends 라는 약어를 사용한다.
확장한다는 뜻이다. 여기서 중요한 것은 무엇을 확장하느냐 이다.

이것을 알아보기 위해 예시를 하나 들겠다.

class Adventure{
	void running(){
	 System.out.println("달리다");
	}
}

-----
class Warrior{
	void running(){
	 System.out.println("달리다");
	}
	void swardSmash(){
	 System.out.println("칼질");
	}
}

-----
class Magician{
	void running(){
	 System.out.println("달리다");
	}
	
	void ignite(){
	 System.out.println("불붙이기");
}
}

-----
class Fighter {
	void running(){
	 System.out.println("달리다");
	}
	
	void punching(){
	 System.out.println("주먹질");
}

Adventure 라는 클래스가 존재하고, Warrior, Magician, Fighter

이런 클래스가 존재할 때, 이 4개의 클래스 중 Warrior, Magician, FighterAdventure 의 코드를 전부 사용하고 있다.


코드에서 보면 running 메소드가 공통적으로 같이 사용되고 있으며
Warrior, Magician, Fighter 클래스가 Adventure 클래스를 기반으로 만들어 지면 간결할 거라 생각되어진다.


이럴 때 사용하는게 보통 상속인데
Adventure 클래스에서 Warrior, Magician, Fighter 로 확장되어 사용되어 지기 때문에 Extends 즉 확장이라 정의한다.

뿐만 아니라 메모리 영역도 확장되어 사용되기 때문에 상속을 위한 예약어는 Inheritance 가 아닌 Extends 이다.

✅ 요약하자면

1.상위 클래스에서 개별적인 내용들이 추가되어 생성 되기 때문에
  확장이라 볼 수 있다.

2.상위 클래스 기반에다.
  하위 클래스의 코드가 추가 되기 때문에
  메모리영역이 확장된다 볼 수 있다.

다형성 ( Polymorphism )

같은 형태를 가지지만 다른 내용 구성을 가지는 것을 다형성이라고
쉽게 정의할 수 있을 것 같다. 객체 지향의 주요 특성 중 하나 이며, 상속을 통한 다형성으로 객체지향적인 프로그래밍을 할 수 있다고 흔히 말한다.

다형성을 이용한 동적 바인딩

class Adventure{
	void running(){
	 System.out.println("달리다");
	}
	
	void skill(){
		System.out.println("달팽이 3마리");
	}
}

-----
class Warrior{
	void running(){
	 System.out.println("달리다");
	}
	void swardSmash(){
	 System.out.println("칼질");
	}
	
	void skill(){
		swardSmash();
	}
}


 public static void main(String[] args) {
	 
	 Adventure warrior = new Warrior()
	 warrior.skill();
 }

상속을 통한 다형성을 이해하기 위해
평소에 내가 이해하는 내용과
묵시적 형변환과 컴파일 시점에 대한 내용으로 설명해볼 예정이다.

내가 이해하고 있던 다형성

 public static void main(String[] args) {
	 
	 Adventure warrior = new Warrior()
	 warrior.skill();
 }

Adventure 로 정의 되었지만 사실 Warrior() 생성자를 사용한 Warrior 인스턴스이다.

WarriorAdventure 의 하위 클래스이고,
위의 내용 대로 WarriorAdventure 의 영역도 포함하고 있다.

Adventure 로 선언이 되었지만
Warrior 의 생성자를 통해서 사용되어 지기 때문에
Warrior 에서 정의된 skill 인 swardSmash();
즉 ‘칼질’ 이 콘솔 화면에 출력 될 것이다.

좀더 멋있게 설명해보자

Adventure warrior = new Warrior()

Adventure warrior = (Adventure) new Warrior()

✅묵시적 형변환

묵시적이라는 것은 암묵적인
즉, 겉으로 표현은 안되지만 모두가 다 아는 그런 느낌이다.
“말 안 해도 알지?” 이런 느낌 이다.

우리가 흔히 상속 관계의 클래스에서 이렇게 사용 하는 것은
사실 묵시적 형변환이 이루어지고 있는 것이다.

자바 Thread 가 해당 부분을 실행할 때, 컴파일 시점에서는 warrior 는 앞의 형인 Adventure 라고 인식한다.

하지만 런타임 시 객체 인스턴스 타입을 기준으로 실행할 메소드가 정해지는데,
컴파일 시점처럼 Adventure 가 아닌 Warrior 의 메소드를 사용한다.

결론

	 Adventure warrior = new Warrior()
	 warrior.skill();

여기서 warrior 의 skill 메소드는 동적 바인딩이 되어 실행되는 것이라 할 수 있다.

정말 결론

정말 기초적인 내용이지만 역시 돌아서면 까먹는 것이다. 그래도 덕분에
이제 절대 안까먹을 것 같다.

0개의 댓글