: 프로그래밍 방법론
: 프로그램을 기능적으로 세분화 시키고, 기능을 모듈화 시킨다. 이때 function(함수)를 사용한다.
ex) C언어
예금 업무, 대출 관련 업무, 외환 관련 업무, 보험 관련 업무로 나뉘고, 각각의 업무를 또 세분화 시킨다.
: "유지보수성"
ex) JAVA(객체 지향 개념을 가장 잘 대변하고 있는 프로그래밍 언어), C++, ...
=> Class 를 이용한 객체 Modeling
Class
: 현실세계에 존재하는 객체를 모델링하는 수단
: instance를 만들어내는 수단
: 새로운 데이터 타입을 만들어내는 수단 - ADT(Abstract Data Type)
상속의 가장 큰 목적 : 코드의 재활용
위에 있는 클래스 : super class, parent class, upper class, base class
아래에 있는 클래스 : sub class, child class, derived class
두개의 클래스가 상속 관계에 있다는 것을 is-A relationship 이라고 부른다.
=> sub class is a super class -> 성립
=> super class is a sub class -> 성립 X
is-A relationship으로 Polymorphism(다형성)이 등장하였다.
"문법적 설탕"
JavaScript는 prototype 기반의 객체지향(객체기반) 언어로 Class가 필요없다. 하지만 사람들의 편리를 위해 ES6부터는 Class를 도입했다.
생성자 함수와 유사하다.
=> Class 자체가 함수이면서 객체인 것이다.
=> instance를 생성할 수 있다.
생성자 함수와 다르게 반드시 "new" keyword가 필요하다.
: class 이름이 아니라 식별자를 사용한다. instance가 실제로 만들어지는 함수는 constructor이다. this keyword와 binding까지 하고 끝나면 묵시적으로 this를 return한다.
class Person {
constructor(name) {
this.name = name;
}
}
const me = new Person('홍길동');
Class간의 상속을 지원한다.
=> "extends", "super" keyword를 사용한다.
Class 역시 hoisting이 발생한다.
=> let, const처럼 hoisting이 된다.
const Person = '안녕하세요';
{
console.log(Person);
class Person {
}
}
실행 결과 : ReferenceError: Cannot access 'Person' before initialization
Class 내부코드는 string mode로 동작한다.
Class 안에는 constructor, prototype 메소드, static 메소드가 있다.
=> 이 property의 property attribute 값은 모두 false이다.
// class define
class Person {
}
// 익명 class 표현식
const Person1 = class {};
// 기명 class 표현식
const Person2 = class MyClass {};
: class는 0개 이상의 method로 구성된다. method는 ES6 축약표현으로 된 method만 나올 수 있다.
class Person {
// constructor(생성자)
constructor(name) {
// instance의 초기화
// instance의 property를 설정한다.
this.name = name;
}
// prototype method
// instance가 실제로 상속해서 사용할 수 있다.
sayHello() {
console.log('안녕하세요');
}
// static method
static sayHi() {
console.log('이건 static');
}
}
const me = new Person('홍길동');
: property임에도 불구하고 [[Value]]를 가지고 있지 않다. 일반적으로 다른 property의 값을 읽어오거나(getter) 저장할 때(setter) 사용한다.
class Person {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
get fullName() {
return `${this.lastName}${this.firstName}`;
}
set fullName(name) {
[this.lastName, this.firstName] = name.split(' ')
}
};
const me = new Person('길동', '홍');
me.fullName = '김 연아';
console.log(me.fullName);
실행 결과 : 김연아
객체 literal에서 접근자 property 사용해보기
// 객체 literal을 이용해서 객체 생성 const Person = { firstName: '길동', lastName: '홍', // get을 이용하면 반드시 return 구문이 존재해야 한다. get fullName() { return `${this.lastName}${this.firstName}`; }, set fullName(name) { // 유효성 검사를 할 수 있다. [this.lastName, this.firstName] = name.split(' ') } }; Person.fullName = '김 연아'; console.log(Person.fullName); 실행 결과 : 김연아
: class의 상속은 extends를 사용한다. prototype 기본 상속과는 다르다
하위 class의 [[Prototype]]나 __proto__에 이어져있는 것이 상위 class이다.
// 상위 class(super class)
class foo {}
// 하위 class(sub class)
class bar extends foo {}
const obj = new bar();
sub class bar는 super class foo의 상속을 받는다
sub class bar의 [[Prototype]]은 super class foo를 가리킨다.
-> class 기반의 상속
super class foo의 [[Prototype]]은 Function의 prototype 객체를 가리킨다.
bar의 prototype 객체의 [[Prototype]]은 foo의 prototype 객체를 가리킨다.
-> prototype 기반의 상속
bar의 instance obj의 [[Prototype]]은 bar의 prototype 객체를 가리킨다.
-> prototype 기반의 상속
foo의 prototype 객체의 [[Prototype]]은 Object의 prototype 객체를 가리킨다.
Function의 prototype 객체의 [[Prototype]]은 Object의 prototype 객체를 가리킨다.
// super class
class Animal {
constructor(age, weight) {
this.age = age;
this.weight = weight;
}
eat() {
return '밥을 먹어요!';
}
move() {
return '움직여요';
}
}
class Bird extends Animal {
constructor(age, weight, kk) {
// 상위 클래스의 constructor를 호출
super(age, weight); // super()보다 this.kk = kk를 먼저 실행할 수 없다.
this.kk = kk
}
fly() {
return '날아요!';
}
}
const bird = new Bird(10, 30, 100);
console.log(bird);
console.log(bird instanceof Bird); // bird가 뒤쪽 class의 instance인지 확인한다.
console.log(bird instanceof Animal);
class Base {
constructor(name) {
this.name = name;
}
sayHello() {
return '안녕하세요!';
}
}
class Derived extends Base {
sayHello() {
return super.sayHello() + this.name;
}
}
const derived = new Derived('홍길동');
console.log(derived.sayHello());
: class간 상속은 가능하지만 생성자 함수간 상속은 불가능하다. class와 생성자 함수는 상속 관계를 가질 수 있다.
=> class는 생성자 함수로부터 상속을 받을 수 있다.
function Base(name) {
this.name = name;
}
class Derived extends Base {}
동적 상속
: extends 키워드 뒤에 값으로 평가될 수 있는 식이 올 수 있다.
JavaScript 특유의 형태이다.function Base1(name) { this.name = name; } class Base2 { } let tmp = true; // 3항 연산자 ( ? ... : ... ) class Derived extends (tmp ? Base1 : Base2) { }