OOP(객체 지향 프로그래밍) 기초 개념

isthis·2022년 4월 11일
0
post-thumbnail

OOP

객체 지향 프로그래밍은 OOP(Object-Oriented Programming)라고도 불리며 프로그래밍 패러다임 중 하나이다. 자바스크립트는 객체 지향 언어가 아니지만, 객체 지향 언어 방식을 지원한다.
자바스크립트로 객체 지향 프로그래밍을 하는 방법에 대해 알아보자.

비디오 게임을 만들 때, 우리는 Player(Object)가 필요하다. 그리고 각각의 Player는 서로 다른 데이터를 가질 것이다. 만약, Player가 여러 명일 경우에는 다음과 같이 코드가 작성될 것이다.

const playerOne = {
	name: "Geonhee",
	skill: "punch",
	health: 90,
};
const playerTwo = {
	name: "Nicolas",
	skill: "kick",
	health: 95,
};
const playerThree = {
	name: "Jaeyong",
	skill: "smile",
	health: 80,
};

위 코드를 살펴보면, 동일한 패턴이 보인다. 각 플레이어들은 모두 같은 속성(property)들을 갖고 있다. 다른 점은 속성의 값들인 데이터 뿐이다.

이런 방식의 문제점은 다음과 같다.

  1. ‘구조'에 대한 고민이 없다.

    → 즉, 플레이어를 구성하는 모습이 어떠해야 한다는 구조에 대한 규칙이 없다.
    따라서 플레이어마다 구조(속성)가 바뀔 수도 있고, 속성을 쓸 때 오타가 발생하여 차이가 생길 수 있다.

  2. 새로운 속성을 추가하기 힘들다.

    → 예를 들어, 모든 플레이어에 ‘경험치' 속성을 추가하려면 일일이 타이핑해야한다.

이러한 방식을 보완하기 위해 일종의 ‘플레이어 팩토리’를 만들면 된다.
데이터만 집어넣으면 데이터를 적용해주는 함수가 있고, 플레이어 객체를 아웃풋으로 얻을 수 있는 팩토리를 말이다. 이를 통해 일일이 복제할 필요도 없고, 오타로 인한 에러도 피할 수 있다. 또한, 경험치 속성을 모든 플레이어들에게 주고 싶을 때, ‘플레이어 팩토리'에서 속성 하나만 추가하면 한번에 업데이트가 된다.

위에서 말한 ‘플레이어 팩토리'는 자바스크립트의 Class라는 개념이다. Class는 객체를 위한 팩토리와 같은 것이다. 같은 속성을 갖고 있지만, 데이터는 다른 경우 사용할 수 있다. 즉, Class는 일종의 구조, 설계도를 만든다.

Class를 사용하여 위 코드를 아래와 같이 바꿀 수 있다.

class Player = {
	constructor(name, health, skill) {
		this.name = name;
		this.skill = skill;
		this.health = health;
		this.xp = 0;
	}
};
// 새로운 플레이어 생성
const geon = new Player("Geonhee", "punch", 90);
const cola = new Player("Nicolas", "kick", 95);
const yong = new Player("Jaeyong", "smile", 80);

이렇게 사용함으로써 얻을 수 있는 효과는 다음과 같다.

  1. 이전처럼 코드를 복사할 필요가 없어졌다.

  2. 그들의 속성(Property)에 접근할 수 있다.

    const geon = new Player("Geonhee", "punch", 90);
    console.log(geon.health);

이처럼 Class는 원하는 모습으로 객체를 찍어낼 수 있는 템플릿과 같은 역할이다.

위 코드에 대해 조금 더 설명을 해보자.
Class에서 새 객체를 만들 때(new Player(...)와 같이) “constructor” 메서드는 Javascript에 의해 자동으로 호출된다. 따라서, constructor 메서드에서 Class가 어떤 속성을 갖게될 것인지 구성을 결정할 수 있다.
또한, constructor는 위 코드와 같이 인수를 받을 수도 있다.
그리고 this라는 것은 플레이어 클래스 내의 속성 및 메서드를 지칭하는 방법이다.

Class는 constructor라는 메서드 외에도 다양한 메서드를 가질 수 있다.

class Player = {
	constructor(name, health, skill) {
		this.name = name;
		this.skill = skill;
		this.health = health;
		this.xp = 0;
	}
	sayHello() {
		return `Hello, my name is ${this.name}`;
	}
};

위 코드처럼 작성하면, Player Class에서 생성된 모든 Object는 sayHello라는 method를 호출할 수 있게 된다. 따라서, 만약 전투 게임을 만든다면, 아래와 같은 함수를 클래스에 추가하여 구현할 수 있다.

takeHit() {
	this.health = this.health - 5;
}

이처럼 method를 사용하여 Class를 더욱 똑똑하게 만들 수 있다.

Class Inheritance(클래스 상속)

상속은 코드 중복을 줄이고, 코드를 재사용 가능한 조각으로 나눌 수 있게 해준다.
OOP에서는 상속을 통해 child(자녀) Class가 parent(부모) Class의 속성을 갖게 할 수 있다.

예를 들어, 위 예시의 Player들은 전부 Player 이전에 다음 코드와 같은 Human이라는 속성을 공통적으로 가진다.

class Human {
	constructor(name) {
		this.name = name;
		this.arms = 2;
		this.legs = 2;
	}
}

이 Human Class에 들어있는 특성(age, arms, legs 등)들을 아래와 같이 적는 대신 ,

class Player {
	constructor(name, health, skill) {
		this.name = name;
		this.arms = 2;
		this.legs = 2;
		this.skill = skill;
		this.health = health;
		this.xp = 0;
}

아래 코드처럼 Human Class에서 확장하면 된다.

class Player extends Human {
	constructor(name, health, skill) {
		this.skill = skill;
		this.health = health;
		this.xp = 0;
	}
}

위 코드처럼 확장하게 되면, Player 클래스가 Human 클래스의 속성을 다 갖고, 추가적으로 그들만의 다른 속성을 갖게 된다.

하지만, 위 코드는 아직 동작하지 않는다.
Human constructor가 인수에 따라 인간의 이름을 정하기 때문이다.
Player 클래스에서 Human 클래스의 constructor method를 호출하려면, Player 클래스의 constructor method에서 super method라는 것을 호출해줘야 한다. 따라서, 다음 코드와 같이 변경하면 작동된다.

class Player extends Human {
	constructor(name, health, skill) {
		super(name);
		this.skill = skill;
		this.health = health;
		this.xp = 0;
	}
}

마치며

이상으로 OOP의 기초적인 개념에 대해 알아보았다.
더 구체적으로 공부하기 위해서는 private, public, protected methods & properties, abstract classes, static methods, interfaces 등등을 배워야 한다.
앞으로 OOP로 코드를 짜는 것도 연습을 해봐야겠다.

참고자료
노마드코더

profile
공부

0개의 댓글