만두의 부트캠프 🤔
  • 2-1. [JavaScript] 객체지향
    2023년 11월 06일 15시 43분 25초에 업로드 된 글입니다.
    작성자: 만두33

     

     

    # 객체지향

     

    자바스크립트는 프로토타입 기반의 객체 지향 언어입니다.

    객체 지향 프로그래밍은 소프트웨어를 객체(데이터와 해당 데이터를 조작하는 메서드로 구성된 개체)로 구조화하는 프로그래밍 패러다임

    객체 지향 프로그래밍은 코드를 재사용하기 쉽고 유지 관리하기 쉽게 만들며, 복잡한 시스템을 모듈화하고 추상화할 수 있습니다.

     

     

     

    <자바스크립트의 객체 지향 프로그래밍 특징>

    특징 설명
    프로토타입 기반 클래스 기반 상속 대신 프로토타입을 사용한 상속 메커니즘을 갖고 있습니다.
    객체 거의 모든 것이 객체로 표현됩니다. 함수, 배열, 문자열, 숫자 등 모든 것이 객체입니다.
    상속 객체는 다른 객체(프로토타입)로부터 속성과 메서드를 상속받을 수 있습니다.
    다형성 다형성을 지원하며, 동적으로 인터페이스를 구현하는 다양한 객체를 다룰 수 있습니다.
    캡슐화 데이터와 관련 동작을 함께 캡슐화하여 객체 내부의 데이터를 외부에서 직접 액세스하지 않습니다.

     

     

     


    # 클래스와 인스턴스

     

    객체지향 프로그래밍 :
    하나의 모델이 되는 청사진을 만들고 (class)
    그 청사진을 바탕으로 한 객체를 만드는(instance)
    프로그래밍 패턴

     

     

    객체를 어떤 식으로 만드는지 살펴보면, 그냥 일반적인 함수를 정의하듯 만듭니다.

    이때 함수를 이용하는 방법이 조금 다릅니다. 그냥 실행하는 것이 아니고 new 키워드를 써서 만듭니다.

    이는 새로운 인스턴스를 만드는 방법입니다.

    일반적인 다른 함수와 구분하기 위해 클래스는 보통 대문자로 시작하며 일반명사로 만듭니다. 
    일반적인 함수는 적절한 동사를 포함하고 소문자로 시작합니다.

     

    클래스는 일종의 원형(original form)으로, 객체를 생성하기 위한 아이디어나 청사진입니다.

    인스턴스는 클래스의 사례(instance object)입니다.

    클래스는 객체를 만들기 위한 생성자(constructor)함수를 포함합니다.

     

     

    class instances
    function Car(color){}
    let avanet = new Car('blue');
    let mini = new Car('cyan');
    let beetles = new Car('red');

     

     

     

    그리고 클래스를 만드는 새로운 문법이 ES6(ECMAScript 6, ECMAScript 2015라고도 합니다)에 도입되었습니다. 

    바로 class 키워드입니다.
    최근에는 ES6 방법을 주로 사용합니다.

     

    class Car{
    	constructor(brand,name,color){
    	//인스턴스가 만들어질때 실행되는 코드
    	}
    }



    여기서 보이는 함수는, 객체지향 프로그래밍에서 생성자(constructor) 함수라고 부릅니다.

    인스턴스가 만들어질 때 실행되는 코드입니다.

    참고로 생성자 함수는 return 값을 만들지 않습니다.

    최근에는 ES6 방법을 주로 사용합니다.

     

    let avante = new Car('hyundai','avante','black');
    let mini = new Car('bmw', 'mini','white');
    let beetles = new Car('volkswagen', 'beetles',red);
    
    //avante, mini, beetles 각각의 인스턴스는 Car라는 클래스의 고유한 속성과, 메소드를 갖습니다.

     

     

    인스턴스를 만들 때에는 new 키워드를 사용합니다.

    즉시 생성자 함수가 실행되며, 변수에 클래스의 설계를 가진 새로운 객체, 즉 인스턴스가 할당됩니다.

    각각의 인스턴스는 클래스의 고유한 속성과 메서드를 갖게 됩니다.

     


    # 속성과 메소드

     

     

    클래스에 속성과 메소드를 정의하고, 인스턴스에서 이용합니다.

     

    객체 지향 프로그래밍(OOP)에서 "속성"은 객체의 특징 또는 상태를 나타내는 데이터를 의미하고, 

    "메서드"는 객체가 수행할 수 있는 동작 또는 함수를 나타냅니다.

     

     

    속성 (Properties) 메소드 (Methods)
    속성은 객체의 상태나 데이터를 나타내며 객체의 특징을 설명합니다. 메서드는 객체가 수행하는 동작 또는 함수를 나타내며
    객체의 행동을 정의합니다.
    속성은 변수 또는 프로퍼티로 표현되며 
    객체 내부 또는 외부에서 액세스할 수 있습니다.
    메서드는 함수로 구현되며 
    객체 내부 또는 외부에서 호출할 수 있습니다.
    각 객체는 고유한 속성을 가질 수 있으며 
    속성의 값은 객체의 상태를 나타냅니다.
    메서드는 객체의 상태를 변경하거나 객체와 관련된 동작을 수행합니다.
    (예) 객체의 이름, 나이, 색상 등이 속성에 해당합니다. (예) 객체의 동작을 실행하는 함수, 객체의 데이터를 수정하는 함수,
    객체 간의 상호작용을 제어하는 함수가 메서드에 해당합니다.

     

    자동차에는 색상, 가격, 속력과 같은 고유의 속성이 있습니다.

    한편, 시작, 후진, 전진, 멈춤과 같이 자동차의 기능이 메서드로 존재합니다.


    # .this

     

    avaScript의 this는 현재 실행 중인 함수나 메서드 내에서 사용되는 특별한 키워드로, 

    실행 컨텍스트 내에서 현재 객체(주로 호출된 객체)를 참조합니다.

     

     this는 인스턴스 객체를 의미합니다. parameter로 넘어온 브랜드, 이름, 색상 등은 인스턴스 생성 시 지정하는 값입니다.

     

    함수가 실행될 때,

    해당 scope마다 생성되는 고유한 실행 context(execution context)

    new 키워드로 인스턴스를 생성했을 때에는,

    해당 인스턴스가 바로 this의 값이됩니다.

     

    더보기
    1. this의 값은 호출 방식에 의해 동적으로 결정됩니다.
      • this는 함수가 호출될 때, 호출 방식 및 호출 위치에 따라 다르게 설정됩니다.
    2. this를 사용하여 현재 객체에 접근할 수 있습니다.
      • 객체의 메서드 내에서 this를 사용하면 해당 객체에 접근할 수 있습니다.
    3. this를 전역 컨텍스트에서 사용할 때, 전역 객체를 가리킵니다.
      • 브라우저에서는 전역 컨텍스트에서 this는 window 객체를 가리킵니다.
    4. 화살표 함수(arrow function) 내에서 this는 자신의 스코프에서 가장 가까운 일반 함수의 this를 상속합니다.
      • 화살표 함수에서 this는 화살표 함수를 감싼 함수나 객체의 this를 상속받습니다.
    5. call, apply, bind 메서드를 사용하여 this 값을 수동으로 설정할 수 있습니다.
      • call 및 apply 메서드를 사용하면 함수를 호출하면서 this를 지정한 객체로 설정할 수 있으며, bind 메서드를 사용하여 this를 설정한 함수를 반환합니다.

     


    # prototype

     

    프로토타입은 모든 JavaScript 객체가 기본적으로 가지고 있는 특수한 객체입니다.

     

    상속 (Inheritance):
      JavaScript에서 객체는 다른 객체(프로토타입)에서 속성과 메서드를 상속할 수 있습니다.
      즉, 하나의 객체가 다른 객체의 프로퍼티와 메서드를 재사용할 수 있습니다.
      이것은 코드 재사용과 구조화에 도움을 줍니다.

    프로토타입 체인 (Prototype Chain):
      JavaScript 객체는 프로토타입 체인을 따라 상위 프로토타입 객체에서 속성 또는 메서드를 찾습니다.
      이것은 객체 간의 상속을 구현하는 핵심 메커니즘입니다.

    프로토타입 객체:
      모든 JavaScript 객체는 프로토타입 객체를 가집니다.
      이 프로토타입 객체에는 해당 객체의 속성 및 메서드가 정의됩니다.
      Object.prototype은 모든 객체의 최상위 프로토타입입니다.
      모든 객체는 Object.prototype을 상속받습니다.

     

     

    프로토타입을 이해하면, 객체 지향 프로그래밍에서 상속 및 메서드 공유를 구현하는 데 도움이 됩니다. 

    객체가 속성 또는 메서드를 찾을 때 프로토타입 체인을 따라 올라가며 검색하므로, 

    해당 객체의 프로토타입과 그 상위 프로토타입들이 속성과 메서드를 제공하면 이를 상속받아 사용할 수 있습니다.

     

     


     

    # constructor

     

    JavaScript에서 constructor는 객체 지향 프로그래밍에서 사용되는 특별한 메서드입니다.

    이 메서드는 객체가 어떻게 생성되었는지를 나타내며, 주로 클래스 또는 생성자 함수에서 객체를 초기화하고 설정하는 데 사용됩니다.

     

    // 생성자 함수 Person
    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    
    // Person 생성자 함수를 사용하여 객체 생성
    const person1 = new Person('Alice', 30);
    const person2 = new Person('Bob', 25);
    
    console.log(person1); // { name: 'Alice', age: 30 }
    console.log(person2); // { name: 'Bob', age: 25 }
    
    // 객체가 생성될 때 constructor에 의해 초기화됩니다.

    위 예제에서 Person은 생성자 함수이며, constructor 메서드는 객체를 초기화합니다. 

    new 키워드를 사용하여 Person 생성자 함수를 호출하면 새로운 객체가 생성되고 

    constructor 메서드가 호출되어 객체의 속성을 초기화합니다.

     

    constructor 메서드는 객체의 생성 시점에 특정 초기화 작업을 수행할 때 유용하며,

     클래스를 사용한 ES6의 클래스 기반 객체 생성에서도 사용됩니다. 

    객체를 생성하는 과정에서 원하는 설정 및 초기화를 수행할 수 있습니다.

     

    더보기

    자바스크립트에서 객체를 만들 때, 

    객체의 생성자 함수(예: `Person` 함수)를 사용하고, `new` 키워드로 객체를 생성하면 

    자바스크립트는 객체에 `constructor` 속성을 자동으로 설정합니다. 

    따라서 `constructor` 속성은 객체가 어떤 생성자 함수로부터 생성되었는지를 가리키는 속성입니다. 

    이것은 내장 동작으로, 개발자가 명시적으로 `constructor` 메소드를 정의하거나 사용할 필요가 없습니다.

    예를 들어, 다음 코드에서:

     

    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    
    const person1 = new Person('Alice', 30);

     


    `Person` 생성자 함수로 `person1` 객체를 생성하면

    `person1` 객체의 `constructor` 속성은 자동으로 `Person` 생성자 함수를 가리키게 됩니다. 

    하지만 이 코드에서 `constructor` 메소드를 명시적으로 호출하거나 사용한 적은 없습니다. 

    `constructor` 속성은 객체가 어떤 생성자 함수에서 만들어진 것인지를 암시적으로 나타내주는 속성입니다.

     


    # 객체 지향 프로그래밍

     

    객체 지향 프로그래밍 (OOP)은 컴퓨터 프로그램을 설계하고 구현하는 데 사용되는 프로그래밍 패러다임 중 하나입니다. 

    이 패러다임은 현실 세계의 객체와 그 객체 간의 상호 작용을 모델링하는 데 중점을 둡니다. 

    OOP는 여러 개념과 원칙으로 구성되며 다음과 같은 중요한 요소가 포함됩니다:

    1. 객체 (Object) : 현실 세계의 엔티티 또는 데이터 구조를 나타내는 프로그래밍의 기본 단위입니다. 

      객체는 데이터 (속성 또는 멤버 변수)와 해당 데이터를 조작하는 메소드 (동작 또는 함수)로 구성됩니다.

    2. 클래스 (Class) : 객체를 생성하기 위한 일종의 템플릿 또는 설계도입니다. 

      클래스는 객체를 만들기 위한 구체적인 속성과 메소드를 정의합니다.

    3. 상속 (Inheritance) : 객체가 다른 객체로부터 속성과 메소드를 상속하는 메커니즘을 제공합니다.

      이것은 코드의 재사용을 촉진하고 계층 구조를 형성하는 데 사용됩니다.

    4. 다형성 (Polymorphism) : 다른 클래스의 객체들이 동일한 메소드 또는 함수를 서로 다른 방식으로 구현할 수 있는 능력을 나타냅니다.

      이를 통해 하나의 메소드를 다양한 객체 유형에서 사용할 수 있습니다.

    5. 캡슐화 (Encapsulation): 데이터와 관련 메소드를 하나의 단일 단위로 묶는 것을 의미합니다.

      이렇게 함으로써 데이터를 보호하고 접근을 제어할 수 있습니다.

     


    캡슐화는 코드가 복잡하지 않게 만들고, 재사용성을 높입니다.
    추상화는 마찬가지로 코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화합니다.
    상속 역시 불필요한 코드를 줄여 재사용성을 높입니다.
    다형성으로 인해 동일한 메서드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해집니다.

     


    OOP의 주요 목표는 코드의 구조와 유지 보수를 개선하며 협업과 코드 재사용을 간소화하는 것입니다. 

    OOP는 복잡한 소프트웨어 시스템을 구축하고 관리하는 데 매우 유용한 방법 중 하나입니다. 

    자바, C++, Python, JavaScript와 같은 다양한 프로그래밍 언어에서 객체 지향 프로그래밍이 지원됩니다.

     


    # 캡슐화 Encapsulation

     

    • 데이터와 기능을 하나의 단위로 묶는 것
    • 은닉(hiding) :  구현은 숨기고, 동작은 노출시킴
    • 느슨한 결합(Loose Coupling) 에 유리 : 언제든 구현을 수정할 수 있음

     

    캡슐화란? 데이터(속성)와 기능(메서드)을 따로 정의하는 것이 아닌, 하나의 객체 안에 넣어서 묶는 것입니다.

    데이터(속성)와 기능(메서드)들이 느슨하게 결합되는 것이죠.

     

    느슨한 결합은 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 

    코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것을 의미합니다. 

     

    캡슐화라는 개념은 "은닉화"의 특징도 포함하고 있는데, 

    은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것입니다.

    따라서, 디테일한 구현이나 데이터는 숨기고, 객체 외부에서 필요한 동작(메서드)만 노출시켜야 합니다.

    은닉화의 특징을 살려서 코드를 작성하면 객체 내 메서드의 구현만 수정하고,

    노출된 메서드를 사용하는 코드 흐름은 바뀌지 않도록 만들 수 있습니다.

    반면 절차적 코드의 경우 데이터의 형태가 바뀔 때에 코드의 흐름에 큰 영향을 미치게 되어 유지 보수가 어렵습니다.

    그래서 더 엄격한 클래스는 속성의 직접적인 접근을 막고, 설정하는 함수(setter), 불러오는 함수(getter)를 철저하게 나누기도 합니다.

     

     


     

    # 추상화 Abstraction

     

    추상화는 내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념입니다.

    예를 들어 전화라는 객체가 있다면, 그 안에는 스피커와 마이크가 존재하고, 서킷 보드 등이 존재하는 등 내부 구현이 되어 있을 것입니다. 

    그러나 실제로 우리가 사용할 때에는, 이러한 존재에 대해서는 생각하지 않고 

    단순히 수화기를 들고 버튼을 눌러서 해결하는 것으로 인터페이스(interface)를 단순화할 수 있습니다.

     

    이러한 추상화를 통해 인터페이스가 단순해집니다. 

    너무 많은 기능들이 노출되지 않은 덕분에 예기치 못한 사용상의 변화가 일어나지 않도록 만들 수 있습니다.

    추상화는 캡슐화와 비교해서 종종 헷갈려 하는 개념 중 하나입니다.

    캡슐화가 코드나 데이터의 은닉에 포커스가 맞춰져있다면, 

    추상화는 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 

    단순한 이름으로 정의하는 것에 포커스가 맞춰져 있습니다.

    클래스 정의 시, 메서드와 속성만 정의한 것을 인터페이스라고 부릅니다. 이것이 추상화의 본질입니다.

     

     


     

    # 상속 Inheritance

     

    상속은 부모 클래스의 특징을 자식 클래스가 물려받는 것입니다.

     

    예를 들어, 사람(Human)이라는 클래스가 있다고 가정해 봅시다. 

    사람은 기본적으로 이름과 성별, 나이와 같은 속성, 그리고 먹다, 자다 등과 같은 메서드가 있다고 볼 수 있습니다.

    추가적으로 학생(Student)이라는 클래스를 작성한다고 생각해 봅시다. 

    그런데 이때 앞서 구현했던 사람(Human) 클래스의 속성과 메서드를 다시 구현한다면 비효율적일 것입니다. 

    학생의 본질은 결국 사람이므로, 

    상속을 이용하여 학생(Student) 클래스는 사람(Human) 클래스를 상속받을 수 있습니다. 

    학생은 추가적으로 학습 내용, 공부하다 와 같은 속성/메서드를 추가합니다.

     

     


     

    # 다형성 Polymorphism

     

    다양한 객체 유형이 동일한 인터페이스를 통해 작동할 수 있는 능력을 의미합니다. 이것은 코드의 유연성을 향상시키며, 동일한 작업을 다양한 객체에 대해 수행할 수 있도록 합니다.

     

    메소드 다형성 (Method Polymorphism):
    다양한 클래스에서 동일한 메소드 이름을 사용하되,
    각 클래스마다 해당 메소드의 구현을 다르게 하는 것을 의미합니다.
    이는 다른 객체에 대해 동일한 메소드 호출을 통해 객체 간의 상호작용을 단순화합니다.
    예를 들어, 여러 도형 클래스가 동일한 계산면적 메소드를 가지면서,
    각 도형에 맞게 메소드가 다르게 구현될 수 있습니다.

    연산자 다형성 (Operator Polymorphism):
    연산자 오버로딩 또는 연산자 다중 정의를 통해 서로 다른 데이터 유형의 객체에 대해 연산자를 사용할 수 있도록 하는 것입니다.
    예를 들어, 문자열 연결 연산자 +는 숫자와 문자열을 모두 다룰 수 있습니다.


    인터페이스 다형성 (Interface Polymorphism):
    동일한 인터페이스를 구현하는 클래스들이 인터페이스에 선언된 메소드를 구현하고,
    이러한 클래스들을 동일한 인터페이스 형식으로 사용하는 것입니다.
    이를 통해 코드가 특정 클래스에 종속되지 않고 일반적인 인터페이스에 따라 작동할 수 있습니다.

     

    다형성은 OOP의 강력한 기능 중 하나로, 코드의 재사용성을 촉진하고 코드의 유지 보수를 단순화합니다. 이를 통해 다양한 객체 유형 간에 일관된 인터페이스를 유지할 수 있으며, 확장성 있는 소프트웨어를 개발하는 데 도움이 됩니다.

     


     

     

     

    끝 

    댓글