[Java] 디자인패턴: 추상화

객체는 상태 와 행위를 가진다. 상태는 행위를 통해서만 변경된다.
HootJem's avatar
Aug 13, 2024
[Java] 디자인패턴: 추상화

1. 프로젝트 생성

notion image
 

2. 객체지향의 핵심

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

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 인 관계만 상속이 가능함.
notion image

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

[HootJem] 개발 기록 블로그