객체 지향 프로그래밍 ?
객체 지향 프로그래밍 (Object-Oriented Programming, OOP)은 프로그램을 개발 소프트웨어 디자인 패러다임 중 하나로,
프로그래밍에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체(Object)로 만들고,
프로그램을 객체들의 집합으로 구성하는 개념에 기반을 두고 객체들간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법입니다.
OOP는 코드의 재사용성, 유지보수성, 확장성 등을 향상시키는 장점이 있어 대규모 소프트웨어 개발에 유용하며,
현대의 많은 프로그래밍 언어들이 객체지향 프로그래밍을 지원하고 있습니다.
객체 ?
객체(Object)란 데이터와 그 데이터를 처리하는 메서드를 포함하는 소프트웨어 모듈.
객체는 클래스(Class)의 인스턴스로, 클래스는 객체를 생성하기 위한 템플릿 역할을 합니다.
객체는 속성(데이터)과 메서드로 구성되어 있으며, 실제로 프로그램에서 동작하는 단위로 사용됩니다.
예를 들어, 자동차 객체는 자동차의 속성(색상, 모델 등)과 동작(주행, 정지 등)을 표현하며,
이를 통해 자동차에 대한 다양한 작업을 수행할 수 있습니다.
객체 지향 프로그래밍 언어
객체지향 프로그래밍을 지원하는 언어로는 C++ , C# , Java , Python , JavaScript , Ruby , Swift 등이 있음.
객체 지향 프로그래밍의 주요 원칙
1. 캡슐화 (Encapsulation)
캡슐화는 데이터(속성)와 관련 메소드를 하나의 단위로 묶어 외부에서 접근을 제한하는 것.
→ 데이터의 무결성을 보호하고 재사용성 높임.
→ 객체의 내부 동작 방식을 숨기고 선택적으로 필요한 부분만 노출시켜 정보를 보호.
예1) 자동차 클래스에서는 연료량, 속도 등의 데이터와 주행, 정차 등의 메소드를 하나로 묶어 자동차 객체를 형성
예2) 감기약 안에는 다양한 성분의 가루약이 섞여있음
예3) 고양이 내부의 상태를 외부에서 설정 불가 고양이 내부의 state
우리가 놀아주고 먹이를 주며(외부 function)으로 내부 state변경
// 자동차 클래스 정의
class Car {
constructor(make, model, year) {
this.make = make; // 제조사
this.model = model; // 모델
this.year = year; // 생산년도
this.isEngineOn = false; // 엔진 상태 (시동 켜짐/꺼짐)
this.speed = 0; // 속도
}
// 시동을 켜는 메서드
turnOn() {
this.isEngineOn = true;
console.log(`${this.make} ${this.model}의 시동이 켜졌습니다.`);
}
// 시동을 끄는 메서드
turnOff() {
this.isEngineOn = false;
this.speed = 0; // 시동을 끄면 속도를 0으로 초기화
console.log(`${this.make} ${this.model}의 시동이 꺼졌습니다.`);
}
// 가속하는 메서드
accelerate() {
if (this.isEngineOn) {
this.speed += 10;
console.log(`${this.make} ${this.model}이 가속 중입니다. 현재 속도: ${this.speed} km/h`);
} else {
console.log(`${this.make} ${this.model}의 엔진이 꺼져 있어 가속할 수 없습니다.`);
}
}
// 감속하는 메서드
decelerate() {
if (this.isEngineOn && this.speed > 0) {
this.speed -= 10;
console.log(`${this.make} ${this.model}이 감속 중입니다. 현재 속도: ${this.speed} km/h`);
} else if (this.isEngineOn && this.speed === 0) {
console.log(`${this.make} ${this.model}의 속도가 이미 0이므로 더 이상 감속할 수 없습니다.`);
} else {
console.log(`${this.make} ${this.model}의 엔진이 꺼져 있어 감속할 수 없습니다.`);
}
}
}
// 추상화된 자동차 객체 생성
const myCar = new Car("Hyundai", "Sonata", 2022);
// 자동차 동작 시연
myCar.turnOn(); // 시동 켜기
myCar.accelerate(); // 가속
myCar.decelerate(); // 감속
myCar.turnOff(); // 시동 끄기
2. 상속 (Inheritance)
기존 클래스의 속성과 동작을 그대로 상속받아 새로운 클래스를 만드는 것
→ 코드 재사용성 촉진, 계층 구조를 만들어 효율적인 관리를 할 수 있습니다.
예) 동물 클래스가 있고 이를 상속받아 개, 고양이 클래스를 만들면 공통적인 특성을 동물 클래스에서 상속받아 사용할 수 있음
// 부모 클래스
class Animal {
constructor(name) {
this.name = name;
}
// 메서드
speak() {
console.log(`${this.name}이(가) 소리를 냅니다.`);
}
}
// 자식 클래스 1
class Dog extends Animal {
// Dog 클래스는 Animal 클래스를 상속받음
// 메서드 오버라이딩
speak() {
console.log(`${this.name}이(가) 짖습니다.`);
}
// 새로운 메서드 추가
fetch() {
console.log(`${this.name}이(가) 공을 가져옵니다.`);
}
}
// 자식 클래스 2
class Cat extends Animal {
// Cat 클래스는 Animal 클래스를 상속받음
// 메서드 오버라이딩
speak() {
console.log(`${this.name}이(가) 야옹 소리를 냅니다.`);
}
// 새로운 메서드 추가
scratch() {
console.log(`${this.name}이(가) 발톱을 갈아요.`);
}
}
// 객체 생성
const myDog = new Dog("멍멍이");
const myCat = new Cat("야옹이");
// 부모 클래스 메서드 호출
myDog.speak(); // 출력: 멍멍이이(가) 짖습니다.
myCat.speak(); // 출력: 야옹이이(가) 야옹 소리를 냅니다.
// 자식 클래스 고유 메서드 호출
myDog.fetch(); // 출력: 멍멍이이(가) 공을 가져옵니다.
myCat.scratch(); // 출력: 야옹이이(가) 발톱을 갈아요.
3. 다형성 (Polymorphism)
다형성은 다른 클래스의 객체를 동일한 기본 클래스의 객체처럼 다룰 수 있는 개념으로
단일 인터페이스나 메서드가 다양한 유형의 객체를 나타낼 수 있고, 다양한 형태로 동작할 수 있는 능력을 말합니다.
→ 유연하고 확장 가능한 코드 작성, 메소드 오버로딩과 메소드 오버라이딩 및 메서드 재정의를 통해 달성될 수 있음.
예) 도형 클래스에서 면적을 계산하는 메소드를 정의하고, 이를 원, 사각형 클래스에서 각각 오버라이딩하여 다양한 도형 객체를 다룰 수 있음 예) Animal 클래스를 상속 받은 강아지/고양이/돼지 클래스는 모두 makeSound() 메서드를 공통적으로 가지고 있지만, 하위 클래스에서 makeSound() 메서드를 실행할 때 "멍멍"/"냐옹"/"꿀꿀" 과 같이 결과가 다를 수 있는 것을 다형성
오버로딩(Overloading) : 같은 이름의 메서드가 매개변수의 유형이나 개수에 따라 다르게 동작하는 것
class Calculator {
// 정수 두 개를 더하는 메서드
add(x, y) {
return x + y;
}
// 실수 두 개를 더하는 메서드
add(x, y) {
return parseFloat(x) + parseFloat(y);
}
}
const myCalculator = new Calculator();
// 정수 더하기
console.log(myCalculator.add(5, 3)); // 출력: 8
// 실수 더하기
console.log(myCalculator.add(2.5, 1.3)); // 출력: 3.8
오버라이딩(Overriding) : 상위 클래스의 메서드를 하위 클래스에서 재정의하여 다른 동작을 수행하는 것.
class Animal {
speak() {
console.log("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
// Animal 클래스의 speak 메서드를 오버라이딩
speak() {
console.log("개가 짖습니다.");
}
}
class Cat extends Animal {
// Animal 클래스의 speak 메서드를 오버라이딩
speak() {
console.log("고양이가 울부짖습니다.");
}
}
const myDog = new Dog();
const myCat = new Cat();
myDog.speak(); // 출력: 개가 짖습니다.
myCat.speak(); // 출력: 고양이가 울부짖습니다.
4. 추상화 (Abstraction)
추상화는 복잡한 시스템을 단순화시켜 공통된 특성을 기반으로 클래스를 모델링하는 것이며,
객체의 중요한 특성을 강조하고 불필요한 세부 사항을 숨기는 것.
→ 복잡성을 줄이고 사용자가 불필요한 세부 사항을 무시하면서 개체의 핵심적인 기능에 집중할 수 있음
예) 게임 캐릭터 클래스에서는 이동, 공격과 같은 핵심 특성만 추상화하여 다양한 캐릭터를 표현할 수 있음 예) 커피머신 구조 모두 알지 않아도 외부에서 버튼으로 사용
// 자동차 클래스 정의
class Car {
constructor(make, model, year) {
this.make = make; // 제조사
this.model = model; // 모델
this.year = year; // 생산년도
this.isEngineOn = false; // 엔진 상태 (시동 켜짐/꺼짐)
this.speed = 0; // 속도
}
// 시동을 켜는 메서드
turnOn() {
this.isEngineOn = true;
console.log(`${this.make} ${this.model}의 시동이 켜졌습니다.`);
}
// 시동을 끄는 메서드
turnOff() {
this.isEngineOn = false;
this.speed = 0; // 시동을 끄면 속도를 0으로 초기화
console.log(`${this.make} ${this.model}의 시동이 꺼졌습니다.`);
}
// 가속하는 메서드
accelerate() {
if (this.isEngineOn) {
this.speed += 10;
console.log(`${this.make} ${this.model}이 가속 중입니다. 현재 속도: ${this.speed} km/h`);
} else {
console.log(`${this.make} ${this.model}의 엔진이 꺼져 있어 가속할 수 없습니다.`);
}
}
// 감속하는 메서드
decelerate() {
if (this.isEngineOn && this.speed > 0) {
this.speed -= 10;
console.log(`${this.make} ${this.model}이 감속 중입니다. 현재 속도: ${this.speed} km/h`);
} else if (this.isEngineOn && this.speed === 0) {
console.log(`${this.make} ${this.model}의 속도가 이미 0이므로 더 이상 감속할 수 없습니다.`);
} else {
console.log(`${this.make} ${this.model}의 엔진이 꺼져 있어 감속할 수 없습니다.`);
}
}
}
// 추상화된 자동차 객체 생성
const myCar = new Car("Hyundai", "Sonata", 2022);
// 자동차 동작 시연
myCar.turnOn(); // 시동 켜기
myCar.accelerate(); // 가속
myCar.decelerate(); // 감속
myCar.turnOff(); // 시동 끄기