서로 관련 있는 데이터와 함수를 객체(하나의 역할을 수행하는 메소드와 변수의 묶음)로 정의해서 서로 상호작용할 수 있도록 프로그래밍 해나가는 것을 말한다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다.
장점
객체지향을 사용하면 중복되는 관련 객체를 재사용할 수 있어 코드의 중복을 어느 정도 줄일 수 있고 관련 있는 객체들의 역할 분담을 좀 더 확실하게 할 수 있어서 가독성이 높아질 수 있다.
- 생산성을 높여준다.
- 유지 보수 및 확장성이 높다.
정보 은닉(Infomation Hiding)
프로그램의 세부 구현을 외부로 드러나지 않도록 특정 모듈 내부로 감추는 것이다.
서로 연관 있는 데이터와 함수들을 오브젝트 안에 담아두고 외부에서 보일 필요가 없는 세부 데이터를 숨겨 높음으로 외부에서 내부 데이터를 변경할 수 없도록 할 수 있다.
일반적으로 세 종류의 접근 제한이 사용된다.constructor
- class를 가지고 instance(object)를 만들 때 항상 호출되는 함수로 데이터를 담아 호출할 수 있다.
- static 이란 키워드를 사용해서 object를 만드는 함수를 제공한다면 private constructor로 설정해두어 static method를 사용할 수 있도록 권장한다.
public
- 클래스의 외부에서 사용 가능하도록 노출시키는 것이다.
- 외부에서 데이터를 확인 또는 변경할 수 있다.
- class 안에서 변수나 함수에 따로 키워드를 사용하지 않으면 기본적으로 public 상태이다.
private
- 클래스의 내부에서만 사용되며 외부로 노출되지 않는다.
- 외부에서 데이터를 확인 또는 변경할 수 있다.
protected
- 다른 클래스에게는 노출되지 않지만, 상속받은 자식 클래스에게는 노출되는 것이다.
- 외부에서 접근할 수 없고 상속받은 class만이 접근이 가능하다.
class Animal {
private emotion: string = '';
private energy: number = 0;
constructor(
private animalType: string,
private name: string,
private gender: string
) {
this.animalType = animalType;
this.name = name;
this.gender = gender;
}
play() {
this.emotion = 'happy';
}
eat(food: number) {
this.energy = food;
}
}
const dog = new Animal('dog', 'sam', 'male');
const cat = new Animal('cat', 'jang', 'female');
예를 들어,
eat
,play
함수를 사용하면서 외부에서는 에너지나 감정이 변화하는 함수를 이해하지 않아도 사용할 수 있다.
class Animal {
private emotion: string = '';
private energy: number = 0;
constructor(
private animalType: string,
private name: string,
private gender: string
) {
this.animalType = animalType;
this.name = name;
this.gender = gender;
}
private energyUp (energy: number) {
this.energy = energy;
}
private energyDown () {
this.energy -=- 1;
}
private happyEmotion () {
this.energyDown();
this.emotion = 'happy';
}
play() {
this.happyEmotion();
}
eat(food: number) {
this.energyUp(food);
this.happyEmotion();
}
}
const dog = new Animal('dog', 'sam', 'male');
dog.eat();
dog.play();
extends
- extends라는 키워드를 사용하여 class를 상속받을 수 있다.
- 상속을 할 때 constructor가 private일 경우 상속이 되지 않는다. public 또는 자식 클래스에서 접근이 가능하도록 protected 키워드를 사용해야 한다.
- 자식 클래스가 부모 클래스의 함수를 이용하고 싶다면 super 키워드로 접근할 수 있다.
- 자식 클래스에서
constructor
는 반드시super
를 호출해야 하며 부모 클래스에서 필요한 데이터를 super를 이용해 전달해 주어야 한다.
상속의 단점: 타입스크립트에서 상속은 두가지 이상 상속받을 수 없으며 부모클래스의 변화가 있을 경우 자식 클래스도 영향을 미치는 단점이 있다.
class Animal {
private emotion: string = '';
private energy: number = 0;
constructor(
private animalType: string,
private name: string,
private gender: string
) {
this.animalType = animalType;
this.name = name;
this.gender = gender;
}
private energyUp (energy: number) {
this.energy = energy;
}
private energyDown () {
this.energy -= 1;
}
private happyEmotion () {
this.emotion = 'happy';
}
play() {
this.happyEmotion();
}
eat(food: number) {
this.energyUp(food);
this.happyEmotion();
}
}
class Dog extends Animal {
constructor(animalType, name, gender) {
super(animalType, name, gender)
}
barking() {
super.energyDown();
return 'wang wang';
}
}
const seryDog = new Dog('dog', 'sery', 'female');
seryDog.barking();
class Animal {
private emotion: string = '';
private energy: number = 0;
constructor(
private animalType: string,
private name: string,
private gender: string
) {
this.animalType = animalType;
this.name = name;
this.gender = gender;
}
private energyUp (energy: number) {
this.energy = energy;
}
private energyDown () {
this.energy -=- 1;
}
private happyEmotion () {
this.emotion = 'happy';
}
play() {
this.energyDown();
this.happyEmotion();
}
eat(food: number) {
this.energyUp(food);
this.happyEmotion();
}
}
class Dog extends Animal {
constructor(animalType, name, gender) {
super(animalType, name, gender)
}
...
barking() {
super.energyDown();
return 'wang wang';
}
...
}
class Cat extends Animal {
constructor(animalType, name, gender) {
super(animalType, name, gender)
}
...
play() {
super.play();
}
...
}
const seryDog = new Dog('dog', 'sery', 'female');
seryDog.barking();
class Animal {
static private emotion: string = '';
static private energy: number = 0;
constructor(
private animalType: string,
private name: string,
private gender: string
) {
this.animalType = animalType;
this.name = name;
this.gender = gender;
}
static makeAnimal (animalType: string, name: string, gender: string) {
return new Animal(animalType, name, gender)
}
private energyUp (energy: number) {
Animal.energy = energy;
}
private energyDown () {
Animal.energy -=- 1;
}
private happyEmotion () {
Amimal.emotion = 'happy';
}
play() {
this.happyEmotion();
}
eat(food: number) {
this.energyUp(food);
this.happyEmotion();
}
}
const dog = Animal.makeAnimal('dog', 'sery', 'female');
class User {
constructor(private name: string, private age: number) {
this.name = name;
this.age = age;
}
get userInfo(): string {
return `name: ${this.name} , age: ${this.age}`
}
get age(): number {
return this.age;
}
set age(num: number) {
if (num < 0) {
throw Error('error')
}
this.age = num;
}
}
const user = new User('sara', 30);
console.log(user.userInfo) // name: sara , age: 30
user.age = 20;
console.log(user.age) // 20
type IOS = {
serialNumber: string
}
interface PhoneIOS {
makePhone(serialNumber: string):IOS
}
class Phone implements PhoneIOS {
constroctor(private serialNumber: string) {
this.serialNumber = serialNumber
}
makePhone(serialNumber: string):IOS {
return { serialNumber: string }
}
}