Giken Dev
article thumbnail
반응형

출처 : 나무위키

 

절차지향 프로그래밍 → 객체지향 프로그래밍(OOP)

 

절차지향 프로그래밍 예제

public class ProceduralExample {

    public static void main(String[] args) {
    
        int width = 5;
        int height = 10;
        int area = calculateArea(width, height);
        
        System.out.println("사각형의 넓이: " + area);
    }

    static int calculateArea(int width, int height) 
    {
        return width * height;
    }
}

-> 이 예제에서는 함수 calculateArea 호출하여 사각형의 넓이를 계산한다.

 

객체지향 프로그래밍 예제

class Rectangle {
    private int width;
    private int height;

    public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public int calculateArea() {
        return width * height;
    }
}

public class OOPExample {
    public static void main(String[] args) {
    
        Rectangle rectangle = new Rectangle(5, 10);
        int area = rectangle.calculateArea();
        
        System.out.println("사각형의 넓이: " + area);
        
    }
}

-> 이 예제에서는 Rectangle 클래스를 정의하고 객체를 생성하여 사용한다. Rectangle 클래스는 데이터 (너비와 높이)와 해당 데이터를 조작하는 메서드 (calculateArea)를 함께 캡슐화한다.

 

절차지향 프로그래밍은 데이터와 함수가 별개로 다루어지는 반면,

객체지향 프로그래밍은 데이터와 함수가 하나의 단위로 묶여있는 객체로 표현한다.

 

 

  • 절차지향 프로그래밍에 어떤 문제가 있었기에?
    • 데이터와 그 데이터에 접근할 수 있는 함수 사이의 연관관계가 낮다 !
    • 캡슐화로 해결 (응집력이 높아짐 )
  • 객체지향 프로그래밍의 장단점
    • 장점:
      • 모듈화와 재사용성: OOP는 객체를 기반으로 하며, 이러한 객체들은 각각 독립적으로 모듈화되어 작성됩니다. 이 모듈화는 코드의 재사용성을 높이고 유지보수를 용이하게 만듭니다.
      • 코드의 가독성과 유지보수성: OOP는 현실 세계의 개념을 코드로 표현하는데, 이는 코드의 가독성을 높이고 코드를 이해하기 쉽게 만듭니다. 또한 코드 변경 및 유지보수가 용이합니다.
      • 상속과 다형성: OOP에서 상속을 통해 새로운 클래스를 만들고, 다형성을 통해 객체가 여러 형태로 동작할 수 있습니다. 이는 코드의 유연성과 확장성을 높입니다.
      • 캡슐화: 객체는 자신의 내부 상태를 숨기고 외부에 필요한 기능만을 노출함으로써 데이터의 보안성을 높이고 부작용을 줄입니다.
      • 객체 지향 분석 및 설계 (OOAD): OOP는 소프트웨어 개발 전반에 걸쳐 객체 지향 분석 및 설계를 쉽게 수행할 수 있게 해줍니다. 이로 인해 프로젝트의 구조를 명확하게 계획하고 구축할 수 있습니다.
      단점:
      • 추상성과 복잡성: 객체 지향은 현실 세계의 개념을 모델링하는데, 때로는 이로 인해 코드가 복잡해질 수 있습니다. 또한, 과도한 추상화는 코드 이해를 어렵게 할 수 있습니다.
      • 성능: 일부 상황에서는 객체 지향 프로그래밍의 추가 오버헤드로 인해 성능 저하가 발생할 수 있습니다. 특히 하드웨어 제약이 있는 고성능 응용 프로그램에서 주의가 필요합니다.
      • 학습 곡선: 객체 지향 개념을 처음 접하는 개발자에게는 학습 곡선이 존재할 수 있습니다. 일부 개발자들은 이러한 추상적인 개념을 이해하기 어려워할 수 있습니다.
      • 설계 시간: 객체 지향 설계에는 초기에 더 많은 시간이 소요될 수 있으며, 잘못된 설계 결정은 나중에 수정하기 어려울 수 있습니다.

 

객체 지향 프로그래밍은 적절한 상황에서 매우 강력한 도구이며, 코드의 구조와 유지보수성을 개선하는   도움을 줍니다. 그러나 상황과 요구사항에 따라 다른 프로그래밍 패러다임 고려하는 것이 중요합니다.

 

 

 

클래스와 상속

 

  • 부모 타입의 필드 중에서, private 만 상속 불가능
  • Child 인스턴스라도 타입이 Parent 인 경우, Child 인스턴스에서 Child 메서드 호출 불가능

 

오버라이딩(overriding) 오버로딩(overloading)

class Animal {
    void makeSound() {
        System.out.println("동물이 소리를 낸다.");
    }
}

class Dog extends Animal {

    // 오버라이딩: 부모 클래스의 메서드를 자식 클래스에서 재정의
    @Override
    void makeSound() {
        System.out.println("개가 짖는다.");
    }
    
    // 오버로딩: 같은 이름의 메서드를 매개변수의 개수 또는 타입에 따라 다양하게 정의
    void makeSound(String barkType) {
        System.out.println("개가 " + barkType + " 소리를 낸다.");
    }
}

public class Main {
    public static void main(String[] args) {
    
        Animal genericAnimal = new Animal();
        
        genericAnimal.makeSound(); // "동물이 소리를 낸다."

        Dog myDog = new Dog();
        myDog.makeSound(); // "개가 짖는다."
        myDog.makeSound("크게 짖는"); // "개가 크게 짖는 소리를 낸다."
    }
}

 

  • Overriding (재정의)
    • 부모 클래스에서 상속받은 메서드를 자식 클래스에서 다시 정의하는 것
  • Overloading (중복정의)
    • 동일한 메서드 이름으로 파라미터, 리턴 타입이 다른 메서드를 여러개 정의하는 것

 

  • 올바른 상속
    • 필드 재사용 O
    • 메서드 재사용 X
    • 메서드 재사용은 전략패턴 구성(Composite) 활용
  • 부모 타입이 할 수 있는 일은, 자식 타입도 할 수 있더야함(리스코프 치환 원칙)

 

리스코프 치환 원칙

 

상위 타입의 객체는 하위 타입의 객체로 대체될 수 있어야 한다.

, 어떤 클래스의 인스턴스가 있을 , 클래스의 하위 클래스의 인스턴스로 대체해도 프로그램의 의도된 동작이 변하지 않아야 합니다. 이를 위반하면 코드의 예측 불가능성과 오류의 가능성이 높아집니다.

 

class Bird {
    void fly() {
        System.out.println("새가 날아갑니다.");
    }
}

class Sparrow extends Bird {
    @Override
    void fly() {
        System.out.println("참새가 날아갑니다.");
    }
}

public class Main {
    static void makeBirdFly(Bird bird) {
        bird.fly();
    }

    public static void main(String[] args) {
    
        Bird bird = new Bird();
        Sparrow sparrow = new Sparrow();

        makeBirdFly(bird); // "새가 날아갑니다."
        makeBirdFly(sparrow); // "참새가 날아갑니다."
    }
}

Bird 객체와 Sparrow 객체 모두 makeBirdFly 메서드에 전달될 수 있고, 예상대로 동작한다.

이것이 리스코프 치환 원칙을 준수하는 예제이다 !

 

 

 

 

 

 

반응형
profile

Giken Dev

@기켄

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!