inblog logo
|
Uni
    Design-Pattern

    (디자인 패턴)추상화

    추상 클래스, 상속, 컴퍼지션
    홍윤's avatar
    홍윤
    Aug 13, 2024
    (디자인 패턴)추상화
    Contents
    1. 프로젝트 생성2. 패키지 만들기3. 객체지향의 핵심4. 상속과 컴퍼지션

    1. 프로젝트 생성

    notion image
     

    2. 패키지 만들기

    notion image
     

    3. 객체지향의 핵심

    💡
    객체는 상태(객체가 생성 될 때)와 행위를 거친다. 상태는 행위를 통해서만 변경한다.

    1. 추상화 연습 예제 및 해설

    package ex00; class 앨리스 { private int 목마름; // 상태는 변경 X public 앨리스(int 목마름) { //객체 this.목마름 = 목마름; } void 물마시기() { // heap에 저장되어있다. 의도를 파악하기 좋다. setter로 할 필요 없다. 목마름 = 0; } int 목마름확인하기(){ //getter는 꼭 필요하다 return 목마름; } } public class Memo01 { public static void main(String[] args) { 앨리스 e = new 앨리스(100); // 9번 라인에서 동적할당 (heap), main 앨리스 // 1. 값 변경(행위) e.물마시기(); // 2. 값 확인 int 목마름 = e.목마름확인하기(); System.out.println(목마름); } }
    ‘앨리스’클래스
    • ‘목마름’ 이라는 정수형 변수를 가지고 있고, ‘private’으로 선언되어 클래스 내부에서만 접근 가능하다.
    • ‘앨리스(int 목마름)’ 생성자는 ‘앨리스’ 객체를 생성할 때 초기’목마름’ 값을 설정했다.
    • ‘물마시기’메소드는 ‘목마름’을 0으로 설정하고 ‘앨리스’ 객체가 물을 마셔 목마름을 해소하는 동작을 의미한다.
    • ‘목마름확인하기’ 메소드를 통해 ‘목마름’ 상태를 반환한다.
    notion image
    ⭐
    2진수 10진수로 변환
    2진수의 각 자리수를 그 자리의 2의 제곱수와 곱한 다음, 그 결과를 모두 더하는 방식입니다. 예를 들어, 2진수 1101을 10진수로 변환하는 방법을 설명하겠습니다.
    notion image
     
    ⭐
    static, heap, stack 변수 정리
     

    1. Static 변수 (정적 변수)

    • 메모리 영역: 데이터 영역 (Data Segment) 또는 BSS (Block Started by Symbol) 영역.
    • 생명 주기: 프로그램이 시작될 때 할당되어 종료될 때까지 유지됩니다.
    • 특징:
      • 전역 변수(global variables)와 정적 변수(static variables)는 이 영역에 저장됩니다.
      • 프로그램의 전체 실행 기간 동안 메모리에서 계속 유지됩니다.
      • 값이 초기화되지 않으면 자동으로 0으로 초기화됩니다.
      • 여러 함수 또는 클래스에 걸쳐 공유될 수 있으며, 프로그램 내에서 하나의 복사본만 존재합니다.
      • 자바에서 정적 변수는 클래스 로딩 시 생성되고, 프로그램 종료 시 소멸됩니다.

    2. Heap 변수 (힙 영역)

    • 메모리 영역: 힙 영역.
    • 생명 주기: 동적 할당(Dynamic Allocation) 시 할당되며, 프로그래머가 명시적으로 해제할 때까지 유지됩니다.
    • 특징:
      • new, malloc(), calloc(), realloc() 등을 통해 동적으로 할당된 메모리.
      • 메모리의 크기와 생명 주기가 유연합니다.
      • 메모리 관리를 프로그래머가 직접 해야 하며, 해제를 잊어버리면 메모리 누수(memory leak)가 발생할 수 있습니다.
      • 자바에서는 가비지 컬렉터(Garbage Collector)가 자동으로 사용되지 않는 메모리를 회수합니다.
      • 객체나 배열 같은 크기가 가변적인 데이터들이 주로 힙에 저장됩니다.

    3. Stack 변수 (스택 변수)

    • 메모리 영역: 스택 영역.
    • 생명 주기: 해당 변수가 선언된 블록이 끝날 때까지 유지됩니다.
    • 특징:
      • 함수 호출 시 할당되는 지역 변수(local variables)와 함수 인자(function arguments)가 저장됩니다.
      • 함수가 호출될 때마다 스택 프레임이 생성되고, 함수가 종료되면 스택 프레임이 제거되면서 그 안의 변수들도 함께 소멸됩니다.
      • 스택은 LIFO(Last In, First Out) 구조를 따르며, 자동으로 메모리가 관리됩니다.
      • 스택 오버플로우(stack overflow) 위험이 있습니다. 이는 함수 호출이 너무 깊거나, 너무 큰 지역 변수를 선언할 때 발생할 수 있습니다.
      • 메모리 할당이 매우 빠르고, 정적 할당된 변수가 스택에 저장됩니다.

    요약

    • Static 변수: 프로그램 실행 전부터 존재하며 프로그램 종료 시 소멸되는 전역적 변수. 초기화하지 않으면 기본값이 할당됩니다.
    • Heap 변수: 동적 메모리 할당 영역에 저장되며, 프로그래머가 관리합니다. 객체나 가변 데이터를 저장하는 데 사용됩니다.
    • Stack 변수: 함수 호출 시 생성되고, 함수 종료 시 소멸되는 지역 변수와 함수 인자. 메모리 관리가 자동으로 이루어집니다.
     
     

    4. 상속과 컴퍼지션

    package ex00; abstract class Car { // car 상태 // car 행위 abstract void run(); // 무효화 } class tico extends Car { //오버라이딩!! 부모의 메소드 재정의 한다. void run() { System.out.println("티코 달린다."); } } class benz extends Car { //오버라이딩!! 부모의 메소드 재정의 한다. void run() { System.out.println("벤츠 달린다."); } } class Sonata extends Car { // 다형성 // Sonata 상태 // Sonata 행위 //오버라이딩!! 부모의 메소드 재정의 한다 void run() { // 재정의 System.out.println("소나타 달린다"); } } class Genesis extends Car { // 다형성 // Genesis 상태 // Genesis 행위 //오버라이딩!! 부모의 메소드 재정의 한다 void run() { System.out.println("제네시스 달린다"); } } public class Memo02 { static void 레이싱(Car car) { car.run(); } public static void main(String[] args) { Car s1 = new Sonata(); // Sonata, Car Car g1 = new Genesis(); // Genesis, Car Car t1 = new tico(); Car b1 = new benz(); 레이싱(t1); 레이싱(b1); } }
    • Car’는 추상 클래스이며, ‘run’이라는 추상 메소드를 정의 하고 있다.
    • 여러개의 차들은 ‘Car’를 상속받아 ‘run’ 메소드를 각각 구현 하고 있다.
    • ‘Memo2’클래스는 ‘레이싱(Car car)’ ,’ Car’ 타입의 객체를 매개변수로 받아 ‘ run’ 메소드를 호출한다.
    • ‘main’메소드는 각자 객체를 생성하고 ‘레이싱()’ 메소드를 통해 각각의 자동타 객체의 ‘run’ 메소드를 호출 하고 있다.
    • 이 프로그램은 다형성을 통해 각각의 자동차 객체가 동일한 메소드(’run’)을 호출 할 때, 실제 객체의 타입에 맞는 동작을 수행하도록 구현된 예제다.

    notion image
    💡
    추상 클래스(abstract class),
    추상 클래스(abstract class)는 객체 지향 프로그래밍(OOP)에서 사용되는 개념으로, 다른 클래스들이 공통적으로 가지는 속성이나 메서드를 정의하는 클래스입니다. 그러나 이 클래스 자체로는 인스턴스(객체)를 생성할 수 없으며, 반드시 이를 상속받아 구현 한 하위 클래스에서 인스턴스를 생성해야 합니다.

    주요 특징:

    1. 추상 메서드(Abstract Method):
        • 추상 클래스는 추상 메서드를 포함할 수 있습니다. 추상 메서드는 메서드의 선언만 있고, 구현은 없는 메서드입니다. 즉, 메서드의 이름, 반환형, 매개변수만 정의하고, 실제 동작 내용(구현)은 하위 클래스에서 제공해야 합니다.
        • 예를 들어, draw()라는 추상 메서드는 "그리기"라는 동작을 의미하지만, 실제로 "어떻게 그릴지"는 하위 클래스가 결정합니다.
    1. 일반 메서드:
        • 추상 클래스는 추상 메서드뿐만 아니라 일반 메서드도 포함할 수 있습니다. 일반 메서드는 하위 클래스에서 그대로 상속받아 사용할 수 있습니다.
    1. 상속을 통해 구현:
        • 추상 클래스는 직접 인스턴스를 생성할 수 없습니다. 반드시 추상 클래스를 상속받은 하위 클래스에서 모든 추상 메서드를 구현한 후에 인스턴스를 생성할 수 있습니다.
    1. 공통된 특성과 동작 정의:
        • 추상 클래스는 여러 하위 클래스가 공통적으로 가져야 할 특성과 동작을 정의합니다. 예를 들어, 다양한 종류의 도형을 그리는 프로그램에서 Shape라는 추상 클래스를 만들고, 이 클래스를 상속받은 Circle, Rectangle 등의 하위 클래스가 각자의 방식으로 draw() 메서드를 구현할 수 있습니다.

    오버라이딩(Overriding)
    오버라이딩(Overriding)은 객체 지향 프로그래밍에서 자식 클래스가 부모 클래스에서 상속받은 메소드를 재정의하는 기능입니다. 이 방식으로 자식 클래스는 부모 클래스의 메소드를 자신의 필요에 맞게 변경할 수 있습니다.

    주요 특징:

    1. 메소드 재정의(Overriding): 자식 클래스에서 부모 클래스의 메소드와 동일한 이름, 매개변수, 반환 타입을 가진 메소드를 정의하면, 이 메소드는 부모 클래스의 메소드를 오버라이드합니다.
    1. 동적 바인딩: 메소드 호출 시, 실제 객체의 타입에 따라 호출되는 메소드가 결정됩니다. 즉, 자식 클래스의 인스턴스에서 호출된 메소드는 자식 클래스에서 정의된 메소드가 됩니다.
    1. 접근 제어자: 자식 클래스의 오버라이딩 메소드는 부모 클래스의 메소드보다 접근 제어가 더 제한적일 수 없습니다. 예를 들어, 부모 클래스의 메소드가 public이라면, 자식 클래스의 메소드도 public이어야 합니다.
    1. 예외 처리: 자식 클래스의 오버라이딩 메소드가 던질 수 있는 예외는 부모 클래스의 메소드가 던지는 예외보다 적어야 합니다.
    즉 오버라이딩을 통해 자식 클래스는 부모 클래스의 기능을 확장하거나 수정할 수 있으며, 이로 인해 코드의 재사용성과 유연성을 높일 수 있습니다.
     
    Share article

    Uni

    RSS·Powered by Inblog