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