도입
명저로 다시보는 자바와 메모리 1편에서 작성한 것과 같이 좋은 실력을 갖춘 개발자가 되기 위해서 단순히 자기의 코드가 돌아갔다 뿐 아니라 자신의 코드가 컴퓨터 내부에서 어떻게 동작하는지를 이해해야 합니다. 1편에서는 main(), 변수, block, static 변수, 멀티 프로세스, 멀티 쓰레드를 살펴보았습니다. 알고 있는 언어의 동작과 비슷해서 어렵지 않았을 것입니다. 본 글에서는 추상화, 상속, 다형성 코드에 대해서 T 메모리에 어떻게 저장되는지 볼 것입니다.
추상화와 T 메모리
public class Mouse {
public String name;
public void sing() { }
}
[Mouse.java]
public class Mouse {
public static void main(String [] args){
Mouse mickey = new Mouse();
mickey.name = "미키";
mickey = null;
}
}
[MouseDriver.java]
- MouseDriver.java의 public static void main(String [] args) 가 실행되기 전 T 메모리 스냅샷은 위의 그림과 같습니다.
- java.lang 패키지와 클래스들이 T 메모리의 스태틱 영역에 배치됩니다.
- 자세히 보면 name에는 변수 저장 공간이 보이지 않고 이름만 존재합니다.
- 객체가 생성되어야만 속성의 값을 저장하기 위한 메모리 공간이 스태틱 영역이 아닌 힙 영역에 할당됩니다.
- 객체 변수 mickey가 Mouse 객체에 대한 참조 변수입니다.
- 객체 변수 mickey가 Mouse 객체의 주소(포인터)를 가지고 있다는 것을 화살표로 표현합니다.
- mickey = null이 실행되면 객체 참조 변수 mickey가 더 이상 힙 영역에 존재하는 Mouse 객체를 참조하지 않습니다.
- 가비지 컬렉터가 아무도 참조해 주지 않는 Mouse 객체를 쓰레기로 인지하고 수거해 갑니다.
- 가비지 컬랙터가 다녀간 T 메모리 상태는 위의 그림과 같습니다.
상속과 T 메모리
public class Animal {
public String name;
public void showName(){
System.out.println("안녕 나는 %s야.", name );
}
}
[Animal.java]
public class Penguin extends Animal {
public String habitat;
public void showHabitat(){
System.out.printf("%s는 $s에 살아", name, habitat);
}
}
[Penguin.java]
public class Driver {
public static void main(String [] args){
Penguin pororo = new Penguin();
pororo.name = "뽀로로";
poeoeo.habitat = "남극";
pororo.showName();
pororo.showHabitat();
Animal pingu = new Penguin();
pingu.name = "핑구";
//pingu.habitat = "EBS";
pingu.showName();
//pingu.showHabitat();
}
}
[Driver.java]
- Penguin 클래스의 인스턴스만 힙 영역에 생기는 것이 아니라 Animal 클래스의 인스턴스도 함께 힙 영역에 생깁니다.
- 그림에서는 생략되었지만 모든 클래스의 최상위 클래스인 Object 클래스의 인스턴스도 함께 생성됩니다.
- pingu 객체 참조 변수가 가리키고 있는 것은 Penguin 인스턴스가 아닌 Animal 인스턴스입니다.
- pingu 객체 참조 변수는 사실 펭귄이지만 동물이라는 것만 인식하고 있습니다.
- 따라서 pingu 객체 참조 변수는 habitat 속성과 showHabitat() 메서드를 사용할 수 없습니다.
다형성과 T 메모리
public class Animal {
public String name;
public void showName(){
System.out.println("안녕 나는 %s야.", name );
}
}
[Animal.java]
public class Penguin extends Animal {
public String habitat;
public void showHabitat(){
System.out.printf("%s는 $s에 살아", name, habitat);
}
// 오버 라이딩 - 재정의: 상위 클래스의 메서드와 같은 메서드 이름, 같은 인자 리스트
public void showName(){
System.out.println("내 이름은 비밀입니다.");
}
// 오버로딩 - 중복정의: 같은 메서드 이름, 다른 인자 리스트
public void showName(String yourName){
System.out.println("%s 안녕, 나는 $s라고 해.", yourName, name);
}
}
[Penguin.java]
public class Driver {
public static void main(String [] args){
Penguin pororo = new Penguin();
pororo.name = "뽀로로";
poeoeo.habitat = "남극";
pororo.showName();
pororo.showName("초보람보");
pororo.showHabitat();
Animal pingu = new Penguin();
pingu.name = "핑구";
pingu.showName();
}
}
[Driver.java]
어머 내 이름은 알아서 뭐하게요?
초보람보 안녕, 나는 뽀로로라고 해
뽀로로는 남극에 살아
어머 내이름은 알아서 뭐하게요?
[실행결과]
위의 코드 실행 결과는 위와 같습니다.
- pororo.showName(); 부분을 실행하면 Animal 객체에 있는 showName() 메서드는 Penguin 객체에 있는 showName() 메서드에 의해 재정의, 즉 가려졌기에 Penguin 객체에서 재정의한 showName() 메서드가 호출됩니다.
- T 메모리에서 주의해야 할 것은 pingu 객체 참조 변수는 타입이 Animal 타입이라는 것입니다.
- Animal 객체의 showName()은 Penguin 객체의 showName()에 의해 가려져 있습니다. 따라서 17번째 줄의 pingu.showName() 메서드를 실행하면 Animal 객체에 정의된 showName() 메서드가 아닌 Penguin 객체에 의해 정의된 showName() 메서드가 실행됩니다.
- 상위 클래스 타입의 객체 참조 변수를 사용하더라도 하위 클래스에서 오버라이딩(재정의)한 메서드가 호출됩니다.
광고 꽝고
'Computer Science > Java-Spring' 카테고리의 다른 글
[로켓 학습] 스프링부트 CRUD REST API (JPA, MySQL, Gradle) (31) | 2021.05.19 |
---|---|
[스프링 시큐리티] 디버깅 로그 출력 방법 (0) | 2021.04.25 |
📘명저로 다시보는 자바와 메모리 이야기 1편 (0) | 2020.03.23 |
📘명저로 다시보는 객체지향 이야기 (0) | 2020.03.22 |
이클립스에서 Java와 Github저장소 연결하기 (0) | 2017.08.14 |