210823 CodeStates 26일차

공윤배·2021년 8월 24일
0

210823 CodeStates 26일차

코드스테이츠의 Section1이 끝나고 Section2의 첫날이다.
Section2부터는 매일 아침 9시부터 1시간 동안 Toy project라는 알고리즘 문제를 한문제씩 풀어야하고 Section1에 비해 수업에서 배우는 내용의 난이도도 조금은 높아질 것 같다.
오늘은 자바스크립트의 프로토타입객체,클래스에 대해 공부했다.

객체지향프로그래밍, 객체지향언어

초기의 프로그래밍 언어는 프로그램의 실행 순서를 따라 명령들을 조합하여 프로그래밍을 하는 절차적언어였다. (대표적인 절차적 언어는 C,포트란 등이 있다.)
시간이 지나면서 객체지향 프로그래밍이라는 패러다임이 등장하면서, 명령어(변수또는 함수)들을 순차적으로 작동하는 방법대신 데이터와 데이터의 처리하는 기능을 하나로 묶은 모형(객체)를 만들어 활용하는 방식을 고안해냈다.
기존의 절차적언어는 프로그램을 명령어들의 집합으로 보는데 반해, 객체지향언어는 프로그램을 독립적인 객체들로 나누고 각각의 객체들이 메세지를 주고받으며 데이터를 처리하는 방식, 즉 프로그램을 객체들의 집합으로 본다.
각각의 객체는 데이터(프로퍼티)와 데이터를 처리하는 기능(메서드)를 포함하고 있다.

객체지향언어의 특징은 캡슐화,추상화,상속,다형성이 있으며 자바스크립트에서는 프로토타입객체를 이용해 상속의 개념을, 클로저를 이용해 캡슐화(정보은닉)의 개념을 구현할 수 있다.
객체지향언어의 특징은 다음에 깊게 다루어봐야할 것 같다.

프로토타입(Prototype)

JS는 Java,C++과 같은 클래스 기반 객체지향언어와는 조금 다른 프로토타입 기반 객체지향언어이다.
클래스 기반 객체지향언어에서는 객체를 생성하기 전에 미리 클래스를 정의해두고 정의된 클래스를 이용해 객체를 생성(인스턴스를 생성)한다.

//java에서의 객체생성
class Student{
    String name;
    int age;
    String grade;
    Student(String name,int age,String grade){
        this.name=name;
        this.age=age;
        this.grade=grade;
    }
    void printInfo(){
        System.out.printf("%s은 %d살이고 학점은 %s입니다.",this.name,this.age,this.grade);
    }
}
//위와같이 클래스를 정의해두고 new 연산자를 이용해 객체 s1을 생성한다.

public class main{
    public static void main(String[] args)
    {
        Student s1=new Student("홍길동",26,"A");
        s1.printInfo();
        //홍길동은 26살이고 학점은 A입니다.
    }
}

하지만 프로토타입기반 객체지향언어인 JS는 클래스없이도 객체를 생성할 수 있었다.

  • 객체리터럴:{}를 이용해 {}안에 프로퍼티와 메서드를 기술한다.
let student={
    name:”홍길동”,
	age:26,
	grade:A,
	print: function(){
		console.log(`${this.name}${this.age}살이고 학점은 ${this.grade}입니다.`)
	}
}
  • Object생성자함수: Object생성자함수를 이용해 빈객체를 생성, 그 후에 프로퍼티와 메서드를 기술한다.
let student=new Object();
student.name=“홍길동”;
student.age=26;
student.grade=A”
student.print=function(){
	console.log(`${this.name}${this.age}살이고 학점은 ${this.grade}입니다.`)	
}
  • 생성자함수: 생성자함수를 정의하고 이를 이용하여 객체를 생성한다.
function Student(name,age,grade){
	this.name=name;
	this.age=age;
	this.grade=grade;
	this.print=function(){
		console.log(`${this.name}${this.age}살이고 학점은 ${this.grade}입니다.`)	
	}
}

let s1=new Student("홍길동",26,"A");

자바스크립트의 모든 객체는 자신의 부모역할을 담당하는 객체와 연결되어 있다.
객체지향의 상속 개념과 같이 부모객체의 프로퍼티 또는 메서드를 상속받아 사용할 수 있게 한다.
이런 부모객체를 Prototype객체, Prototype이라 부른다.
Prototype객체는 생성자함수로 생성된 객체들에게 공유 프로퍼티를 제공하기 위해 사용된다.

자바스크립트의 모든 객체는 [[Prototype]]이라는 인터널 슬롯을 가진다.
[[Prototype]]의 값은 Prototype객체이며 부모객체의 프로퍼티와 메서드들에 대한 정보를 담고있어 자식객체에서도 사용할 수 있게끔 해준다.
__proto__프로퍼티로 Prototype객체에 접근할 수 있다.

따라서 JS의 모든 객체는 자신의 프로토타입 객체를 가르키는 [[Prototype]]이라는 인터널 슬롯을 가지며 상속을 위해 사용된다.
함수도 객체이므로 [[Prototype]]슬롯을 갖지만, 함수는 일반 객체와 달리 prototype프로퍼티도 갖고있다.

[[Prototype]]은 모든 객체가 갖고 있는 인터널 슬롯으로 해당 객체의 부모역할을 하는 프로토타입 객체를 가리킨다.
prototype프로퍼티는 함수객체만이 갖고있는 프로퍼티로 해당 함수가 생성자로 사용될때 생성될 객체의 부모 역할을 하는 프로토타입 객체를 가리킨다.

constructor 프로퍼티
프로토타입 객체는 constructor프로퍼티를 갖는다.
이 constructor프로퍼티는 객체의 입장에서 자신을 생성한 객체(생성자함수)를 가리킨다.
생성자 함수의 this키워드는 생성자함수로 생성되는 객체(instance)를 가리킨다.

프로토타입 체인
자바스크립트는 객체의 프로퍼티나 메서드에 접근하려 할때 해당 객체에 접근하려는 프로퍼티나 메서드가 없을경우 [[Prototype]]이 가리키는 링크를 따라 부모역할을 하는 프로토타입 객체의 프로퍼티나 메서드를 차례대로 검색하는데 이를 프로토타입 체인이라한다.

클래스

자바스크립트의 클래스
자바는 대표적인 객체지향언어로 클래스를 이용해 객체를 생성한다.
자바스크립트는 클래스가 없이 객체를 생성할 수 있다.
ECMA Script6부터는 자바스크립트도 클래스를 사용할 수 있게 되었다.

클래스는 class키워드를 사용하여 정의한다.
생성자 함수와 마찬가지로 new연산자를 이용하여 객체를 생성한다.(클래스로 인스턴스를 생성)
클래스 안의 constructor은 인스턴스를 생성하고 변수를 초기화하기 위한 특수한 메서드이다.
생략을 해도 에러는 발생하지 않는다. (constructor(){}와 동일하게 작동한다.)
클래스는 한개의 constructor만을 가질 수 있다.

class Student{
  constructor(name,age,grade){
    this.name=name;
    this.age=age;
    this.grade=grade;
  }
  print(){
    console.log(`${this.name}은(는) ${this.age}살이고 학점은 ${this.grade}입니다.`);
  }
}
let s1=new Student("홍길동",26,"A");
s1.print();
// 홍길동은(는) 26살이고 학점은 A입니다. 

클래스의 상속
상속은 코드의 재사용이 이루어질 때 굉장히 유용하다.
새롭게 정의할 클래스가 기존에 정의된 클래스와 유사하다면, 상속을 통해 기존의 클래스의 프로퍼티와 메서드를 받아와서 바뀌는 부분만을 구현하면 되기 때문이다.
extends 키워드를 사용하여 상속을 정의할 수 있다.
super키워드는 부모클래스의 constructor을 호출할 때, 부모 클래스를 참조할 때 사용된다.
상속을 받는 자식의 constructor에는 반드시 super를 이용해 부모클래스의 constructor을 호출해야만 한다.

class Student2 extends Student{
    constructor(name,age,grade){
        super(name,age,grade);
    }
    print(){
        console.log("Student2의 출력입니다.");
        super.print();
    }
}
let s2=new Student2("김철수",27,"B");
s2.print();
// Student2의 출력입니다.
// 김철수은(는) 27살이고 학점은 B입니다.

print함수의 오버라이딩
print라는 동일한 이름의 함수가 Student2클래스로 생성된 s2객체의 프로토타입에도 존재하고
Student클래스로 생성된 s1의 객체에도 존재한다.
s2에서 print함수를 호출하면 s2의 프로토타입에 존재하는 print함수를 실행하고 그 과정에서 super.print(부모 클래스 Student클래스에서 정의한 print함수)를 실행하게 된다.

0개의 댓글