클래스로 객체의 자료 구조와 기능을 정의하고, 생성자를 통해 인스턴스를 생성
객체 생성에 사용되는 패턴, blueprint로, new 연산자를 통한 인스턴스화 과정이 필수적임.
자바스크립트는 명령형, 함수형, 프로토타입 기반의 객체 지향 언어이다.
- 이미 생성된 인스턴스의 자료 구조와 기능을 동적으로 변경할 수 있음.
- 프로토타입의 체인, 클로저 개념을 통해 객체 지향의 상속, 캡슐화(정보 은닉) 구현 가능.
자바스크립트에는 다른 클래스 기반의 언어에서 사용하는 동일한 개념의 클래스 개념은 없지만, "객체 리터럴, Object() 생성자 함수, 생성자 함수" 객체 생성 방법을 지원한다.
- ES6에서 등장한 class도 내부는 prototype으로 구성되어 있다.
1. literal
2. new 생성자 함수
3. Object.create();
// 객체 리터럴
var obj1 = {};
// Object() 생성자 함수
var obj2 = new Object();
// 생성자 함수
function F() {}
var obj3 = new F();
1. {} Object literal
변수에 직접 객체를 작성해 넣는 방법.
const soundBox = {
volume: 0,
volumeUp: function() {
if (this.volume < 10) {
this.volume++;
}
},
volumeDown: function () {
if (this.volume > 0) {
this.volume--;
}
}
};
// 객체 리터럴 방식의 단점
soundBox.volume = 500;
2. new 생성자 함수
new 연산자는 사용자 정의 객체 타입 또는 내장 객체 타입의 인스턴스를 생성한다.
3. Object.create()
Object.create(obj.prototype)은 obj.protytpe을 protytpe으로 하는 객체를 생성하는 것.
생성자 함수(Constructor - 클래스이자, 생성자의 역할)와 new 연산자를 통해 인스턴스를 생성하는 자바스크립트.
//생성자 함수(Constructor)
function Person(age){
this.age = age; // 프로퍼티
this.setAge = function(age){ // 메소드
this.age=age;
}
this.getAge = function(){ // 메소드
return this.age;
}
}
//인스턴스 생성
let rm = new Person(20){
console.log(rm.getAge()); //20
}
//메서드 호출
rm.setAge(17);
console.log(rm.getAge()); //17
프로토타입 : 다른 객체를 가리키는 내부 링크
프로토타입 체인 : 프로토타입을 통해 직접 객체를 연결하는 것.
function Person(age){
this.age = age;
}
// 프로토타입 객체에 메소드 정의
Person.prototype.setAge = function(age){
this.age=age;
}
Person.prototype.getAge = function(){
return this.age;
}
let rm = new Person(20);
let amy = new Person(27);
console.log(rm); // Person {age: 20}
console.log(rm); // Person {age: 27}
console.log(Person.prototype);
// Person { setAge: [Function], getAge: [Function] }
자바스크립트 : 프로토타입을 통해 객체가 다른 객체로 직접 상속된다.
function soundBox() {
this.volume = 0;
Headphone.prototype.volumeUp = function () {
if (this.volume < 10) {
this.volume++;
}
}
Headphone.prototype.volumeDown = function () {
if (this.volume > 0) {
this.volume--;
}
}
}
const box1 = new soundBox();
const box2 = new soundBox();
// 외부에서 내부 값을 변경할 수 있음
soundBox.volume = 500;
function factorySoundBox () {
let volumne = 0;
return {
volumeUp: function () {
if (volume < 10) {
volume++;
}
},
volumeDown: function () {
if (volume > 0) {
volume--;
}
}
};
}
const box1 = factorySoundBox();
const box2 = factorySoundBox();
자식 생성자 함수의 프로토타입 프로퍼티를 부모 생성자 함수의 인스턴스로 교체하여 상속 구현.
- 클래스 기반 언어의 상속 방식을 흉내내는 것.
[문제점]
//부모 생성자 함수
var Parent = ( function(){
//생성자 함수
function Parent(age){
this.age = age;
}
//메소드
Parent.prototype.tellAge = function(){
console.log('I'm ' + this.age +' years old';
};
// 생성자 함수 반환
return Parent;
}()
);
//자식 생성자 함수
var Child = ( function(){
// 생성자 함수
function Child(age){
this.age = age;
}
// 자식 생성자 함수의 프로토타입 객체를 부모 생성자 함수의 인스턴스로 교체.
Child.prototype = new Parent();
// 메소드 오버라이드
Child.prototype.tellAge = function(){
console.log('내 나이는 ' + this.age);
}
//askAge 메서드는 Parent 생성자 함수 인스턴스에 위치하게 됨.
Child.prototype.askAge = function(){
console.log('네 나이는 뭐야? 내 나이는 ' + this.age);
}
return Child;
}()
);
let child = new Child('7');
console.log(child); // Parent { age: 7 }
console.log(Child.prototype); // Parent { age: undefined, tellAge: [Function], askAge: [Function] }
child.tellAge(); //내 나이는 7
child.askAge(); //네 나이는 뭐야? 내 나이는 7
Object.create 함수를 사용하여 객체에서 다른 객체로 직접 상속을 구현하는 방식
var Parent = ( function(){
//생성자 함수
function Parent(age){
this.age = age;
}
//method
Parent.prototype.tellAge = function(){
console.log('I'm '+ this.age);
};
return Parent;
}()
);
create 함수의 인수는 프로토타입
var child = Object.create(Parent.prototype)
child.age = 7;
child.tellAge(); //I'm 7
캡슐화 : 관련있는 멤버 변수와 메소드를 클래스와 같은 하나의 틀 안에 담고 외부에 공개될 필요가 없는 정보는 숨기는 것, 정보 은닉
특정 속성을 외부에 노출시키지 않고 내부에서만 조작하는 방법
즉시 실행 함수에 노출시키지 않을 데이터를 변수에 담아 scope로 묶어놓고, 반환되는 객체 메소드에서만 접근할 수 있도록 하는 방법
const soundBox = (function () {
let volume = 0;
return {
volumeUp: function() {
if (volume < 10) {
volume++;
}
},
volumeDown: function () {
if (volume > 0) {
volume--;
}
}
};
})();
한 객체가 여러 가지 '형태'를 가질 수 있음을 의미하며, 같은 이름의 메소드나 함수를 호출했을 때, 그 동작이 실행되는 객체의 타입에 따라 다르게 작동하게 하는 것.
같은 이름의 메소드나 함수가 객체의 타입에 따라 다르게 동작할 수 있도록 하는 '다형성'은 코드의 재사용성과 유연성, 가독성을 향상시킨다.
class Animal {
makeSound() {
console.log('Some generic animal sound');
}
}
class Dog extends Animal {
makeSound() {
console.log('Woof! Woof!');
}
}
class Cat extends Animal {
makeSound() {
console.log('Meow! Meow!');
}
}
let myAnimal = new Animal();
myAnimal.makeSound(); // Some generic animal sound
let myDog = new Dog();
myDog.makeSound(); // Woof! Woof!
let myCat = new Cat();
myCat.makeSound(); // Meow! Meow!
1. 객체지향 프로그래밍(Object-Oriented Programming, OOP)이란?
객체 지향 프로그래밍(Object-Oriented Programming, OOP)은 프로그래밍 패러다임 중 하나로, 데이터와 기능을 하나로 묶어 객체(object)라는 단위로 표현(객체는 데이터와 그 데이터를 조작하는 함수를 캡슐화함)하는 방법론입니다. OOP는 실세계의 객체와 그 객체들 간의 상호작용에 초점을 둠으로써, 더 직관적이고 유연한 설계와 코드 재사용성을 증가시키는 것을 목표로 합니다. 객체지향의 주요 원칙에는 캡슐화, 상속, 다형성이 있습니다.
2. 캡슐화(Encapsulation)란 무엇인가?
캡슐화는 객체의 내부 상태를 외부로부터 숨기고, 오직 정의된 인터페이스를 통해서만 접근을 허용하여 체의 내부 데이터를 보호하는 것.
이는 객체의 내부 구현을 수정하더라도 해당 객체를 사용하는 코드에는 영향을 미치지 않게 하는 장점이 있습니다.
3. 상속(Inheritance)이란?
상속은 기존 클래스의 속성과 메소드를 새로운 클래스가 물려받는 기능입니다. 이를 통해 코드의 재사용성이 높아지고, 유지 보수가 쉬워집니다.
(장점 : 코드 재사용성 증가 및 확장성)
그러나 잘못 사용하면 오버라이딩 오류나 불필요한 코드 복잡성을 초래할 수 있습니다.
4. 다형성(Polymorphism)이란?
다형성은 하나의 인터페이스나 클래스가 다양한 형태로 동작할 수 있게 하는 기능입니다. 예를 들어, 같은 메소드 이름을 가지지만 파라미터나 반환값이 다른 여러 함수를 정의할 수 있습니다.(같은 이름의 메서드가 다른 기능을 하는 것을 허용한다.) 이를 통해 코드의 유연성과 가독성이 향상됩니다.
5. 추상화(Abstraction)란?
복잡한 시스템을 간단한 개념으로 표현하는 것. 핵심적인 부분만을 표현함으로써 복잡성을 줄이고 명확하게 만든다.
6. 추상 클래스와 인터페이스의 차이는?
추상 클래스는 구현되지 않은 메소드를 포함할 수 있으며 상속을 통해 사용됩니다. 한 클래스는 하나의 추상 클래스만 상속할 수 있습니다. 인터페이스는 구현체가 없는 메소드만을 가지며, 다중 상속이 가능합니다. 추상 클래스는 상태(멤버 변수)를 가질 수 있지만, 인터페이스는 상태를 가질 수 없습니다.
7. Composition과 Aggregation의 차이는?
Composition은 한 객체가 다른 객체를 포함하며, 내부 객체의 생명주기가 외부 객체와 연결되어 있는 경우를 말합니다. Aggregation은 한 객체가 다른 객체를 포함하되, 내부 객체가 독립적인 생명주기를 가질 수 있는 경우를 말합니다.
8. 객체 지향 프로그래밍이 가지는 장단점은?
[장점]
[단점]