[웹 개발 기초 자바스크립트] 10. OOP란?

Shy·2023년 8월 27일
0

NodeJS(Express&Next.js)

목록 보기
11/39

OOP (Object-Oriented Programming)

OOP(객체 지향 프로그래밍, Object-Oriented Programming)는 컴퓨터 프로그래밍의 패러다임 중 하나로, 프로그램을 객체들의 모임으로 간주하고 이들 간의 상호작용으로 표현하는 방법론이다. OOP는 데이터와 그 데이터를 처리하는 함수를 하나의 단위로 묶어서 생각하며, 이 단위를 '객체(object)'라고 부른다.

OOP의 주요 특징 및 원칙은 다음과 같다.

  • 캡슐화 (Encapsulation)
    • 객체의 상태를 나타내는 데이터와 메서드를 하나로 묶는 것을 말한다.
    • 외부에서 직접 데이터에 접근하는 것을 제한하고, 메서드를 통해서만 데이터에 접근하도록 하는 기법이다.
  • 상속 (Inheritance)
    • 하나의 클래스에서 정의된 특징(속성 및 메서드)을 다른 클래스가 상속받아 사용할 수 있게 하는 것이다.
    • 코드 재사용을 증진시키며, 기존의 코드를 수정하지 않고도 기능을 확장할 수 있게 합니다.
  • 다형성 (Polymorphism)
    • 하나의 인터페이스나 메서드가 다양한 형태로 동작하는 것을 의미한다.
    • 예를 들어, 같은 메서드 이름이지만 인자의 타입이나 개수에 따라 다르게 동작할 수 있다.
  • 추상화 (Abstraction)
    • 복잡한 시스템을 간단한 개념으로 표현하는 것입니다.
    • 객체 지향 시스템에서는 클래스를 사용하여 복잡한 문제 도메인을 간단하고 일관된 방법으로 표현한다.
  • 종속성 역전 (Dependency Inversion)
    • 상위 모듈이 하위 모듈에 의존하는 전통적인 프로그래밍 방식과는 달리, OOP에서는 하위 모듈이 상위 모듈에 의존하도록 설계하는 원칙이다.

OOP는 이러한 원칙과 특징을 기반으로 시스템을 더 모듈화하고, 재사용성을 높이며, 확장성 있는 설계를 도모한다. 주요 프로그래밍 언어 중 Java, C++, Python, C#, Ruby 등 많은 언어들이 객체 지향 프로그래밍 패러다임을 지원한다.

객체 지향 프로그램이 나오기 이전에는 명령어의 목록을 나열(절차 지향)하는 기능 구현을 목적으로 작성했지만 이렇게 코드를 길게 작성하다 보면 매우 알아보기 힘든 복잡한 코드들이 만들어 진다. 그래서 하나의 문제를 해결을 위한 독립된 단위인 객체로 만들었으며, 이 객체로 인해 알아보기 쉽고 재사용성이 높아졌다.

class Car {
	// 여러 메서드를 정의할 수 있다.
    constructor { ... }
    method1() {...}
    method2() {...}
    method3() {...}
}

class Animal {
	constructor {...}
    method1() {...}
    method2() {...}
    method3() {...}
}

자료 추상화(Abstraction)

자료 추상화는 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단히 만드는 것이다.
이렇게 해서 그 객체 안에 자세한 내용을 몰라도 중요 정보를 이용해서 해당 객체를 사용할 수 있게 된다.

예를 들어, 커프를 마시기 위해서 커피머신을 이용할 줄 알면 커피 머신이 어떻게 작동하는지 몰라도 커피를 마실수 있는 것과 같다.

상속

상속은 새로운 클래스가 기존의 클래스의 자료와 연산을 이용할 수 있게 하는 기능이다. 상속을 받는 새로운 클래스를 부클래스, 파생 클래스, 하위 클래스, 자식 클래스라고 하며 새로운 클래스가 상속하는 기존의 클래스를 기반 클래스, 상위 클래스, 부모 클래스라고 한다. 상속을 통해서 기존의 클래스를 상속받은 하위 클래스를 이용해 프로그램의 요구에 맞추어 클래스를 수정할 수 있고 클래스 간의 종속 관계를 형성함으로써 객체를 조직화 할 수 있다.

다형성

다형성(Polymorphism)은 객체 지향 프로그래밍(OOP)의 주요 특징 중 하나로, 한 인터페이스나 클래스가 다양한 형태로 동작하는 것을 의미한다. 다형성은 크게 컴파일 시간 다형성(정적 다형성)과 실행 시간 다형성(동적 다형성)으로 구분될 수 있다.

컴파일 시간 다형성 (정적 다형성)

  • 주로 메서드 오버로딩(Overloading)을 통해 구현된다.
  • 메서드 오버로딩은 같은 이름의 메서드를 여러 개 가지되, 그 메서드들의 매개변수의 타입이나 개수가 다른 것을 의미한다.
  • 컴파일 시점에 어떤 메서드를 호출할지 결정되므로 '정적'이라는 표현을 사용한다.
class MathOperation {
    add(a, b) {
        return a + b;
    }
    
    add(a, b, c) {
        return a + b + c;
    }
}

실행 시간 다형성 (동적 다형성)

  • 주로 메서드 오버라이딩(Overriding)과 관련 있다.
  • 메서드 오버라이딩은 하위 클래스에서 상위 클래스의 메서드를 재정의하는 것을 의미한다.
  • 프로그램 실행 중에 어떤 메서드를 호출할지 결정되므로 '동적'이라는 표현을 사용한다.
class Animal {
    void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void sound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    void sound() {
        System.out.println("Cat meows");
    }
}

위의 예제에서 Animal 클래스의 인스턴스를 통해 sound() 메서드를 호출하면 "Animal makes a sound"라는 메시지가 출력된다. 그러나 Dog 또는 Cat 클래스의 인스턴스를 통해 동일한 sound() 메서드를 호출하면 각각 다른 결과("Dog barks" 또는 "Cat meows")를 출력한다.

다형성의 장점은 다음과 같다.

  • 확장성: 새로운 클래스를 추가하거나 기존 클래스를 수정하는 것이 용이한다.
  • 재사용성: 기존 코드를 재사용하여 시스템을 개발할 수 있다.
  • 유연성: 다양한 타입의 객체에 대해 동일한 인터페이스를 사용할 수 있다.

다형성은 프로그램을 더 유연하고 확장 가능하게 만들어주며, 객체 지향 프로그래밍의 핵심 요소 중 하나이다.

캡슐화

캡슐화는 클래스 안에 관련 메서드, 변수 등을 하나로 묶어준다.
이 메커니즘을 이용해서 바깥에서의 접근을 막아 보안이 강화되고 잘 관리되는 코드를 제공한다.

캡슐화(Encapsulation)는 객체 지향 프로그래밍(OOP)의 핵심 원칙 중 하나로, 객체의 상태와 행위를 함께 묶는 것을 의미한다. 이 원칙의 주요 목표는 객체의 내부 데이터와 그 데이터를 조작하는 메서드를 하나의 '캡슐' 안에 보관하며 외부에서 직접 접근할 수 없게 하는 것이다.

캡슐화의 주요 특징 및 장점은 다음과 같다.

정보 은닉 (Information Hiding)

  • 객체의 내부 상태는 보통 private 또는 protected 접근 제어자를 통해 숨겨진 상태로 유지됩니다. 이를 통해 객체의 상태를 임의로 변경할 수 없도록 합니다.
  • 외부에서는 해당 객체의 메서드를 통해서만 객체의 상태에 접근하거나 변경할 수 있다.

API 제공

  • 객체는 자신의 기능을 사용하기 위한 명확한 인터페이스(API)를 제공한다. 이를 통해 사용자는 객체의 내부 구현에 대해 알 필요 없이 해당 객체를 사용할 수 있다.

유지 보수성

  • 객체의 내부 구현이 캡슐화되어 있기 때문에, 필요한 경우 내부 구현을 변경해도 외부 코드에 영향을 주지 않게 된다.

제어된 접근

  • Getter와 Setter 메서드를 통해 객체의 상태에 접근하거나 변경하는 것을 제어할 수 있다. 예를 들어, 특정 조건에 따라 값을 설정하거나 반환하는 로직을 적용할 수 있다.

다음은 캡슐화의 예제이다.

public class Person {
    // private 변수로 정보를 숨김
    private String name;
    private int age;

    // 생성자
    public Person(String name, int age) {
        this.name = name;
        this.setAge(age);
    }

    // Getter 메서드
    public String getName() {
        return name;
    }

    // Setter 메서드
    public void setName(String name) {
        this.name = name;
    }

    // Getter 메서드
    public int getAge() {
        return age;
    }

    // Setter 메서드에서 나이의 유효성 검사
    public void setAge(int age) {
        if (age > 0) {
            this.age = age;
        } else {
            System.out.println("Invalid age");
        }
    }

위의 Person 클래스에서는 name과 age라는 private 변수를 사용하여 정보를 은닉하고, 외부에서 이 값을 접근하거나 수정할 때는 Getter와 Setter 메서드를 통해서만 가능하게 한다. 이를 통해 age 값을 잘못 설정하는 것을 방지할 수 있다.

profile
초보개발자. 백엔드 지망. 2024년 9월 취업 예정

0개의 댓글