2장
1. 추상화와 메모리
추상화(abstraction)는 객체를 분해해서 목적에 맞는 특성만 추출해 재조립한 뒤 간단한 형태로 표현하는 것이다. 즉 추상화란 모델링이다.
public class Mouse {
public String name;
public int age;
public int countOfTail;
// public static int countOfTail = 1;
public void sing() {
System.out.println(name + "찍찍!");
}
}
public class MouseTester {
public static void main(String[] args) {
Mouse mickey = new Mouse();
mickey.name = "미키";
mickey.age = 1928;
mickey.countOfTail = 1;
Mouse jerry = new Mouse();
jerry.name = "제리";
jerry.age = 1940;
jerry.countOfTail = 1;
Mouse pikachu = new Mouse();
pikachu.name = "피카츄";
pikachu.age = 1996;
pikachu.countOfTail = 1;
mickey.sing();
jerry.sing();
pikachu.sing();
}
}

전처리를 실행한다.
new Mouse();를 호출했으므로 힙 영역에 클래스의 프로퍼티와 메서드를 가진 Mouse 객체가 생성된다. main 메서드의 스택 프레임에 mickey 변수를 위한 공간을 만든다. mickey는 참조 변수이므로 Mouse 객체를 가리키는 주소값 0x100을 저장한다. 그리고 객체의 변수에 값을 할당한다.
mickey 객체와 마찬가지로 jerry 객체를 만들고 값을 할당한다.
pikachu 객체를 만들고 값을 할당한다.
만일 Mouse 클래스에서 주석 처리한 것처럼 countOfTail이 static 변수라면 클래스의 변수가 되어 static 영역에 생성 및 초기화된다.
사실 String은 객체이므로 객체 내부의 변수 공간에 할당되지 않는다. 그림은 약식으로 표현한 것임을 참고하자. 또한 객체는 JVM의 가비지 컬렉터에 의해 참조되지 않는 시점에서 제거된다.
2. 상속과 메모리
상속(Inheritance)은 하위 클래스가 상위 클래스의 특성을 재사용 및 확장하는 것이다. 상속은 "is a kind of"관계를 만족한다.
public class Animal {
public String name;
public void showName() {
System.out.println("내 이름은 " + name + "입니다.");
}
}
public class Penguin extends Animal {
public String habitat;
public void showHabitat() {
Systetm.out.println(name + "은 " + habitat + "에 살고 있습니다.");
}
}
public class PenguinTester {
public static void main(String[] args) {
Penguin pororo = new Penguin();
pororo.name = "뽀로로";
pororo.habitat = "남극";
Animal pingu = new Penguin();
pingu.name = "핑구";
}
}

전처리를 실행한다.
new Penguin();를 호출했으므로 힙 영역에 클래스의 프로퍼티와 메서드를 가진 Penguin 객체가 생성된다. Penguin과 더불어서 Animal 클래스의 인스턴스도 함께 힙 영역에 생성된다. main 메서드의 스택 프레임에 pororo 변수를 위한 공간을 만든다. pororo는 참조 변수이므로 Penguin 객체를 가리키는 주소값 0x100을 저장한다. 그리고 객체의 변수에 값을 할당한다.
pororo 객체에 값을 할당한다. pororo와 마찬가지로 pingu 객체가 생성된다. pingu 객체는 Penguin 생성자 메서드로 생성했지만 Animal 객체의 인스턴스이므로 Penguin 클래스의 속성과 메서드를 사용할 수 없다. 정확히 말하면 pingu 객체는 암묵적 형변환이 된 것이다.
사실 객체의 조상인 Object 클래스도 상속되고 있으므로 힙 영역에 표시되어야 한다. String과 마찬가지로 편의상 생략 되었음을 참고하자.
3. 다형성과 메모리
다형성(Polymorphism)은 상위 타입이 하위 타입을 참조하는 것이다. 다형성은 오버로딩과 오버라이딩을 통해 구현된다.
public class Animal {
public String name;
public void showName() {
System.out.println("내 이름은 " + name + "입니다.");
}
}
public class Penguin extends Animal {
public String habitat;
public void showHabitat() {
Systetm.out.println(name + "은 " + habitat + "에 살고 있습니다.");
}
@Override
public void showName() {
System.out.println("오버라이딩 한 메서드입니다.");
}
public void showName(String yourName) {
System.out.println("네 이름은 " + yourName + "입니다.");
}
}
public class PenguinTester {
public static void main(String[] args) {
Penguin pororo = new Penguin();
pororo.name = "뽀로로";
pororo.habitat = "남극";
Animal pingu = new Penguin();
pingu.name = "핑구";
pororo.showName();
pororo.showName("루피");
pororo.showHabitat();
pingu.showName();
}
}

전처리를 실행한다.
pororo 객체를 생성하고 값을 할당한다. Penguin 클래스가 Animal 클래스의 showName 메서드를 오버라이딩 했으므로 Animal이 정의한 showName 메서드는 가려진다. 따라서 showName(): void 메서드를 호출하면 Penguin에서 정의한 showName(): void 메서드가 호출된다.
pingu 객체를 생성하고 값을 할당한다. pingu는 Animal 클래스의 인스턴스지만, showName(): void를 호출하면 Penguin에서 오버라이딩한 showName(): void 메서드가 호출된다.
4. 캡슐화
캡슐화(Encapsulation)는 클래스의 프로퍼티와 메서드를 묶어 외부로부터 데이터를 감추고 보호하는 것이다. 캡슐화는 접근 제어자를 통해 이루어진다.
public: 모두 접근 가능
protected: 상속/같은 패키지 내의 클래스에서 접근 가능
(default): 같은 패키지 내의 클래스에서 접근 가능
private: 본인만 접근 가능
참고 자료
스프링 입문을 위한 자바 객체 지향의 원리와 이해 - 위키북스
Last updated