[JS]オブジェクト向けプログラミング(OOP)の基礎


オブジェクト向けプログラミング


1.概念

  • モデルの青写真を作成し、その青写真に基づいてオブジェクトのプログラミングモード
  • を作成する.
  • のプロセス向けプログラミングとは異なり、データと機能集中処理
    *プログラム言語:シーケンスコマンドの組合せ
  • プロパティとメソッドは、「オブジェクト」概念に含まれます.
    *JavaScriptを内蔵するobjectとは異なり、Classという名前の
  • を使用します.
  • JavaScript:オブジェクト向けの言語ではありませんが、オブジェクト向けのモードで
  • を記述できます.

    2.特徴


    1)パッケージ

  • データ(属性)と機能(方法)を組み合わせた
  • コードは再利用可能で複雑ではありません

    (1)非表示(非表示)

  • 非表示:
  • 非表示の実装は、内部データまたは内部実装が外部に露出しないように、対象の外部に必要な動作のみを暴露する(方法).
  • 厳格なクラス:属性への直接アクセスを阻止し、設定された関数(setter)と読み込まれた関数(getter)を徹底的に区別する
    const Cat = function(name) {
      this.name = name
    }
    
    const KKAKKA = new Cat('KKAKKA')
    KKAKKA.name = 'GGAGGA'
    
    console.log(KKAKKA)
    // Cat {name: "GGAGGA"}
    // KKAKKA의 이름이 GGAGGA로 바뀜
  • エンクロージャを使用する方法
  • const Cat = function(name) {
      const a = name
      this.getName = function() {
        console.log(a)
      }
    }
    
    const KKAKKA = new Cat('KKAKKA')
    KKAKKA.name = 'GGAGGA'
    
    console.log(KKAKKA)
    // Cat {name: "GGAGGA", getName: ƒ}
    
    KKAKKA.getName()
    // KKAKKA
    // 외부에선 값을 얻을 수만 있고 바꿀 순 없음
  • キーワードの使用方法:#name
  • class Cat {
      #name
      constructor(name) {
        this.#name = name
      }
    }
    
    const KKAKKA = new Cat('KKAKKA')
    KKAKKA.#name = 'GGAGGA'
    //에러 발생 : Private field '#name' must be declared in an enclosing class

    (2)松結合に有利

  • 実施
  • は随時変更可能である.
  • ばらばら結合:コードの実行順序に従ってステップに従ってコードを記述するのではなく、コードが表す実際の状況に従ってコードを組み合わせて
  • を組み合わせる.

    2)抽象

  • の内部実施は非常に複雑であるが、実際に暴露された部分は非常に簡単である:
  • 簡単なインターフェース:
  • はあまり機能を露出していないので、意外な使用変化を防ぐことができます.

    3)継承


    子クラスは
  • 親クラスのフィーチャーを継承します.
    *派生クラス(派生クラス)基本クラス(ベースクラス)の特徴を継承する
  • サブクラス固有のプロパティ:追加可能なその他のプロパティ/メソッド
  • 4)多形性(重合状態)

  • は様々な形態を提供することができる:
  • 、同じ方法を採用しても、異なる方法で実施することができる.

    クラスを使用したモジュール化


    1.対象

  • 属性(属性):キー値ペアを表す
  • メソッド:オブジェクトを呼び出します.方法()
    *矢印関数は使用できません
  • 2.クラス


    1) ES6

    class Cat {
      // 생성자(constructor) 함수
      constructor(name, color, age) { // 속성
        this.name = name
        this.color = color
        this.age = age
      }
      sayHello() { // 메소드
        return `Hello, I'am ${this.name}`
      }
    }
    
    console.log(Cat.prototype)
    // {constructor: ƒ, sayHello: ƒ}
    // 	constructor: class Cat
    // 	sayHello: ƒ sayHello()
    // 	__proto__: Object
    
    const KKAKKA = new Cat('KKAKKA', 'Black', 7)
    console.log(KKAKKA)
    // Cat {name: "KKAKKA", color: "Black", age: 7}
    // 	age: 7
    // 	color: "Black"
    // 	name: "KKAKKA"
    // 	__proto__:
    // 	  constructor: class Cat
    // 	  sayHello: ƒ sayHello()
    // 	  __proto__: Object
    for(key in KKAKKA) {
      console.log(key)
    }
    // name, color, age
    // 메소드는 제외됨
  • 青写真
  • 類名:大文字で始まる一般名詞
    *一般的な関数:適切な動詞を含み、小文字で始まる
  • プロパティ:name、color、age
  • コンストラクション関数:インスタンスの作成時に実行されるコードを使用しないで戻り値を作成します.
    *this:インスタンスオブジェクトを表す
  • メソッド:オブジェクトに付属する関数と構造関数を組み合わせてclassキーワード内で
  • を定義します.

    2) ES5

    // 생성자(constructor) 함수
    function Cat(name, color, age) { // 속성
      this.name = name
      this.color = color
      this.age = age
      this.eat = function() {
        console.log('eating...')
      }
    }
    
    Cat.prototype.legs = 4
    Cat.prototype.sayHello = function() { // 메소드
      return `Hello, I'am ${this.name}`
    }
    
    // 위의 코드는 아래처럼도 가능하지만 아래의 경우 constructor 명시 필요
    // Cat.prototype = {
    //   constructor : Cat,
    //   legs = 4,
    //   sayHello = function() { // 메소드
    //   	return `Hello, i'am ${this.name}`
    //   }
    // }
    
    console.log(Cat.prototype)
    // {legs: 4, sayHello: ƒ, constructor: ƒ}
    // 	legs: 4
    // 	sayHello: ƒ ()
    // 	constructor: ƒ Cat(name, color, age)
    // 	__proto__: Object
    
    const KKAKKA = new Cat('KKAKKA', 'Black', 7)
    console.log(KKAKKA) 
    // Cat {name: "KKAKKA", color: "Black", age: 7, eat: ƒ}
    // 	age: 7
    // 	color: "Black"
    // 	eat: ƒ ()
    // 	name: "KKAKKA"
    // 	__proto__:
    // 	  legs: 4
    // 	  sayHello: ƒ ()
    // 	  constructor: ƒ Cat(name, color, age)
    // 	  __proto__: Object
  • プロトタイプキーワードを使用して、プロトタイプに
  • を格納することができる.

    3.例

    let KKAKKA = new Cat('KKAKKA', 'Black', 7)
    
    KKAKKA.color // Black
    KKAKKA.age // 7
    KKAKKA.sayHello() // Hello, i'am KKAKKA
  • 青写真に基づいて作成されたオブジェクト
  • インスタンスの作成:新しいキーワード
  • を使用
  • ジェネレータ関数が実行され、クラスの設計と同様に変数に新しいオブジェクト(インスタンス)が作成されます.
  • インスタンス:一意のプロパティとメソッド
  • を持つ

    Prototype

    const Cat = {
      legs: 4,
      sleep() {
        console.log("slepping...")
      }
    }
    
    const KKAKKA = {
      name : "KKAKKA",
      color : "Black"
    }
    
    KKAKKA.__proto__ = Cat
    
    console.log(KKAKKA.legs) //4
    // KKAKKA 객체엔 legs가 없지만 __proto__로 Cat을 상속받음
    // KKAKKA.legs : KKAKKA 객체에 legs가 없으므로  __proto__에서 legs를 찾음
    for (key in KKAKKA) {
      console.log(key)
    }
    // name, color, legs, sleep
    // 상속받은 key까지 모두 나옴
    // .hasOwnProperty를 이용하면 for in 문에서도 상속된 property는 나오지 않게 할 수 있음
    
    Object.keys(KKAKKA) // ["KKAKKA", "Black"]
    Object.values(KKAKKA) // ["KKAKKA", "Black"]
    // 상속된 property는 나오지 않음
    const KKAKKA2 = {
      name : "KKAKKA2",
      color : "gray"
    }
    
    KKAKKA2.__proto__ = KKAKKA
    console.log(KKAKKA2.legs) //4
    // 상속은 계속됨
    // legs가 KKAKKA2에 없어 KKAKKA로 올라가 찾고, 
    // KKAKKA에도 없으면 Cat으로 올라가 찾음 = Prototype Chain
    const KKAKKA = {
      name : "KKAKKA",
      color : "Black",
      legs : 5
    }
    console.log(KKAKKA.legs) //5
    // KKAKKA.legs : KKAKKA 객체에 legs있으므로 KKAKKA 객체에서 legs를 찾음
  • JavaScript:継承メソッドと属性のテンプレートとして、すべてのオブジェクトにプロトタイプオブジェクト(prototype object)を持つプロトタイプベースの言語
  • プロトタイプオブジェクトは、親オブジェクトからメソッドとプロパティを再び継承することもできます(=プロトタイプチェーン)
  • .
  • によって継承された属性およびメソッドは、各オブジェクトではなく、属性内でオブジェクト作成者のプロトタイプとして定義される.
  • プロトタイプ:モデル青写真を作成するプロトタイプオブジェクト(元のフォーマット)
  • 1.クラスとプロトタイプ

    Cat.prototype.constructor === Cat // true
    Cat.prototype === KKAKKA.__proto__ // true
    Cat.prototype.sayHello === KKAKKA.sayHello // true
  • Catプロトタイプの作成者はCat
  • Catの原型には
  • がある
  • KKAKKA.sayHelloはCatprototype.sayHello
  • 参照
  • new CatによるKAKAインスタンス
  • の作成

    2.プロトタイプチェーン

  • プロトタイプチェーン(Prototype Chain):
  • は、あるオブジェクトで別のオブジェクトで定義されたメソッドとプロパティを使用できるようにします.
  • 継承:JavaScriptでの実装時にプロトコルチェーンを使用する
    *extendsおよびsuperキーワード
  • を使用
  • extends:継承用
  • super :
    -コンストラクション関数をサブクラスに書き込む
    -子メソッドに親メソッドと同じ名前のメソッドがある場合は、親メソッドを拡張するときに
  • を使用します.
    class Person {
      constructor(name) {
        this.name = name
      }
      sleep() { 
        console.log('sleeping...')
      }
    }
    
    const somin = new Person('somin')
    
    class Student extends Person{
      constructor(name, age) {
        super(name)
        // super 키워드가 없으면 에러 발생
        // super를 통해 먼저 부모의 constructor를 실행해줘야 함
        // 이때 인자도 받아서 넘겨줘야 함
        this.age = age
      }
      sleep() { 
        super.sleep()
        // super 키워드가 없으면 자식 메소드로 덮어씌워져 'zzz...'만 나옴
        // super 키워드 사용 시 부모의 메소드 사용으로 'sleeping...'도 나옴
        console.log('zzz...')
      }
      learn() { 
        console.log('learning...')
      }
    }
    
    const park = new Student('park', 16) 
    
    console.log(park)
    // Student {name: "park", age: 16}
    // 	age: 16
    // 	name: "park"
    // 	__proto__: Person
    // 	  constructor: class Student
    // 	  learn: ƒ learn()
    // 	  sleep: ƒ sleep()
    // 	  __proto__:
    // 	    constructor: class Person
    // 	    sleep: ƒ sleep()
    // 	    __proto__: Object
    
    park.name // 'Park'
    park.learn() // 'learning...'
    park.sleep() // 'sleeping...', 'zzz...'
    
    park instanceof Student // true
    park instanceof Person // true
    park.__proto__ // Person

    References


    1.継承とプロトタイプ
    2.クラス