1. 프로젝트 생성


2. 객체지향의 핵심
객체는 상태와 행위를 가진다. 상태는 행위를 통해서만 변경한다.
package ex00;
class 엘리스 {
private int 목마름;
public 엘리스(int 목마름) {
this.목마름 = 목마름;
}
void 물마시기(){ // 의도를 파악하기 좋다.
목마름 = 0;
}
int 목마름확인하기(){ // getter를 써도 된다.
return 목마름;
}
}
public class Mem01 {
public static void main(String[] args) {
엘리스 e = new 엘리스(100); // 9번 라인에서 동적 할당 (heap)
// 1. 값 변경
e.물마시기();
// 2. 값 확인
int 목마름 = e.목마름확인하기();
System.out.println(목마름);
}
}메모리는 static, stack, heap 세가지 영역이 존재한다.
JVM이 실행될 때, static 메모리가 먼저 실행되고, 그 다음 main이 진행되며 main 의 stack 메모리가 활성화 된다.
main 안의 엘리스가 new 됨에 따라 엘리스 stack 메모리가 생성되고, 목마름이 heap 메모리에 생긴다.
클래스의 getter는 상태 확인용으로 그냥 사용해도 괜찮지만, setter의 경우 상태 변경을 위해 setter 사용 보다는 새로운 상태 변경을 나타내는 메서드를 생성하는 것이 용이하다.
3. 다형성과 동적 바인딩(Override)
package ex00;
/**
* 목표 : 다형성, 동적바인딩
* 1. 소나타(오브젝트 == 객체), 제네시스(오브젝트 ==객체) == 자동차(추상)
*/
abstract class Car { // new x
abstract void run();
}
class Sonata extends Car{
@Override // 재정의
void run() {
System.out.println("소나타 달린다");
} // sonata -> car
}
class Genesis extends Car{
@Override // 재정의
void run() {
System.out.println("제네시스 달린다");
} // genesis -> car
}
public class Mem02 {
public static void main(String[] args) {
Car s = new Sonata(); // 메모리 sonata(run), car(run)
// car의 run을 호출하러 갔더니, sonata가 run을 재정의해서,
// car의 run의 오버라이드(무효화)되고, sonata의 run이 호출된다.
s.run();
Car g = new Genesis(); // 메모리 genesis(run), car(run)
g.run();
}
}
추상화(abstract)는 객체의 타입을 정해주고, 전체적으로 모듈화 시키기에 적합하다.
부모 객체에서 타입과 메서드를 정하고, 자식 객체에서 extend 하여 이를 받고 메서드를 재정의 할 경우 부모의 메서드는 무효화되고 동적바인딩 되어 자식의 메서드가 실행된다.
객체를 추상화 할 때, 메서드도 같이 추상화 시켜야 extend를 받아 자식 객체를 작업할 때 오류를 줄일 수 있다. 또한, override를 통해 쉽게 재정의 할 수 있다.
Share article