1. 프로젝트 생성

2. 객체지향의 핵심
객체는 
상태 와 행위를 가진다.
상태는 행위를 통해서만 변경한다.RAM 은 저장공간으로, 데이터를 8bit 형식으로 저장한다.
RAM 내에는 JVM 의 주요 메모리 영역인  
Stack Heap static 이 존재한다.- 스택(stack) : 메서드 호출과 지역변수 저장.
- 힙 (heap): 런타임 중 동적으로 할당되는 obj와 같은 객체를 저장함
- 스테틱 (static): 객체 인스턴스가 아닌 클래스에 속하는 정적 변수나 메서드를 저장함

2-1. 예시 코드
package ex00;
class Minji {
    // new 할 때 힙에 할당됨. static이 아니기 때문
    private int 목마름;
    public Minji(int 목마름) {
        this.목마름 = 목마름;
    }
    //setter: 상태 변경. set목마름 대신 물마시기로 의도를 더 명확히 표현.
    void 물마시기(){
        목마름 = 0;
    }
    //getter : 상태확인
    int 목마르니(){
        return 목마름;
    }
}
public class Mem01 {
/*
// hello() 메서드 호출 시, num 변수가 스택에 할당되고, 메서드 종료 시 스택에서 사라짐
// 메서드가 `static` 인지 여부와 상관없이 메서드가 호출될 때 
// 로컬 변수와 호출 관련 정보는 스텍에 저장됨
    static void hello(){
        int num = 10;  
    }
 */
    public static void main(String[] args) {
    // 여기서 힙에 Minji 객체가 동적 할당되고, main 스택의 obj가 이를 참조함
        Minji obj = new Minji(100); 
        //Minji obj2 = new Minji(200);
				//hello();
				
        // 1. 값 변경(행위)
        obj.물마시기();
        // 2. 값 확인
        int 목마름 = obj.목마르니();
        System.out.println(목마름);
    }
}
3. 상속과 컴포지션
Is 인 관계만 상속이 가능함.

1) 상속 (Inheritance)
- 상속은 "Is-A" 관계에서 사용된다. 즉, 특정 클래스가 다른 클래스의 특수한 유형인 경우 상속을 사용한다.
- 예를 들어, "스포츠카"는 “자동차"의 한 종류이므로 sportCar클래스는Car클래스를 상속받을 수 있다.
2) 컴포지션 (Composition)
- 컴포지션은 "Has-A" 관계에서 사용된다. 즉, 특정 클래스가 다른 클래스의 구성 요소로 포함되는 경우 사용된다.
- 예를 들어, "자동차"는 "엔진"을 가지고 있다. Car클래스는Engine클래스를 포함할 수 있다.
3) 재정의 (Override)
- 자식 클래스가 부모 클래스의 메서드를 동일한 이름과 시그니처로 다시 정의하는 것을 의미합니다.
- 재정의된 메서드는 자식 클래스의 인스턴스에서 호출되며, 부모 클래스의 동일한 이름의 메서드를 무효화합니다.
4) 동적 바인딩 (Dynamic Binding)
- 동적 바인딩은 런타임 시점에 어떤 메서드가 호출될지를 결정하는 과정으로, 자식 클래스에서 재정의된 메서드가 호출되면, 자식 클래스의 메서드가 실행된다.
5) 추상 클래스와 추상 메서드 (abstract)
- 추상 클래스는 추상 메서드를 포함할 수 있는 클래스이다. 추상 메서드는 메서드의 구현이 없는 메서드로, 자식 클래스에서 반드시 구현해야 한다.
- 추상 클래스는 인스턴스화할 수 없으며, 다른 클래스에서 상속받아 사용된다.
3-1. 예시코드
package ex00;
// 추상 클래스: 인스턴스를 직접 생성할 수 없으며, 자식 클래스에서 상속받아 구현해야 함
abstract class Car {
    // 추상 메서드: 자식 클래스에서 반드시 구현해야 하는 메서드
    abstract void run(); // 부모의 추상 메서드로 자식 클래스에서 구체적으로 구현됨 (무효화)
}
// 'Car'를 상속받은 자식 클래스 '티코'
// '티코'는 'Car'의 구체적인 구현체로, 'run()' 메서드를 오버라이딩함
class 티코 extends Car{
    
    void run() {
        System.out.println("티코 달린다."); // 'Car' 클래스의 추상 메서드를 오버라이딩하여 구체화함
    }
}
class Sonata extends Car{ // 다형성: 상위 클래스 타입으로 참조할 수 있음
    // Sonata 상태
    // Sonata 행위
    void run(){ // 재정의
        System.out.println("소나타 달린다");
    }
}
class Genesis extends Car{ // 다형성: 'Car'로 참조할 수 있지만, 실제로는 'Genesis'의 'run()'이 실행됨
    // Genesis 상태
    // Genesis 행위
    void run(){
        System.out.println("제네시스 달린다");
    }
}
public class Mem02 {
// 다형성을 활용한 메서드: 'Car' 타입의 객체라면 어떤 인스턴스든 받아
// 'run()' 메서드를 호출할 수 있음
    static void 레이싱(Car car){
    // 전달된 'Car' 타입 객체의 실제 인스턴스에 따라 적절한 'run()' 메서드가 실행됨
        car.run(); 
    }
    public static void main(String[] args) {
        Car s1 = new Sonata(); // Sonata, Car
        Car g1 = new Genesis(); // Genesis, Car
        Car t1 = new 티코();
        // 만약 Sonata s1 = new Sonata(); 이면 레이싱() 메서드를 호출 할 수 없음
        레이싱(t1);
    }
}
Share article