OOP(1) 객체지향 프로그래밍, 클래스
✏️객체지향 프로그래밍(OOP)란?
'사람이 세계를 보고 이해하는 방법을 흉내 낸 방법론'이다.
객체(Object)
객체란 말 그대로 대상을 나타내는 단어이다.
예를 들어, 사람 개인 한 명 한 명을 모두 객체라 할 수 있고, 책, 물건 등을 객체라고 할 수 있다.
사람은 생김새와 성격이 똑같을 수는 없기 때문에 개인의 객체라고 할 수 있고, 책도 내용이 같을지는 몰라도 한 권의 책에 흠집을 낸다고 해서 모든 책들이 전부 흠집이 나는 것이 아니기 때문에 객체라고 할 수 있다.
객체는 속성과 동작으로 구성되어 있다.
자바에서는 이 속성과 동작을 각각 필드(field)와 메서드(method)라고도 부른다.
다시 정리하자면 객체 = 속성 + 행동이다.
속성은 객체의 특징이나 상태를 말하고, 행동은 행동, 동작, 기능 등으로 구성된 대상을 의미한다.
예를 들어 아이폰이라는 객체가 있는데 여기에서 속성은 크기, 길이, 높이, 색상, 해상도 등을 의미한다.
행동은 무엇인가? 객체의 기능(function) - 메서드(method), 함수(function), 행위(behavior)
아이폰이 화면이 켜지는 행동, 사용자로부터 키보드 입력을 받는 행동 모두 '행동'이다.
아이폰의 기능 : 전원 on/off, 잠금해제, 볼륨 up/down. 메시지 보내기, 사진 및 영상 촬영 등을 의미한다.
객체지향 프로그래밍(Object Oriented Programming)
객체지향 프로그래밍(OOP)은 '객체'들을 가지고 프로그래밍을 하는 것이다. (객체 지향형 언어)
객체지향 프로그래밍은 실제 세계에 기반한 모델을 만들기 위해 추상화를 사용하는 프로그래밍 패러다임이라고 한다.
객체 지향 언어로는 JAVA, C++, C# 등이 있다.
클래스(class)와 인스턴스(instance)
객체 지향 프로그래밍은 '클래스(Class)'라는 것을 기반으로 한다.
클래스는 객체의 속성과 행동을 코드로 적어둔 것을 말한다.
예시를 통해 알아보자면 아이폰이라는 객체들이 공통적으로 갖는 속성들(색상, 무게)등 이 있는데, 이런 일반적인 속성들을 정의해둔 것이 클래스이다.
클래스의 속성들에 구체적인 값을 부여해주면 '객체'를 정의할 수 있게 된다.
클래스의 변수에 구체적인 값을 할당하면 객체를 정의할 수 있다는 것이다.
class iphone(크기, 길이, 높이, 색상, 해상도) {
constructor(){
this.크기 = 크기;
this.길이 = 길이;
this.높이 = 높이;
this.색상 = 색상;
this.해상도 = 해상도;
this.잠금해제 = function() {잠금 해제};
this.키보드입력 = function() {키보드 입력};
}
}
var iphone7 = new iphone7('크기', '길이', '높이', '색상', '해상도')
var iphoneX = new iphoneX('174g', '70.9mm', '143.6mm', '실버', '2436x1125')
객체지향 프로그래밍의 특징 4가지
1. 캡슐화(Encapsultation)
캡슐화는 한 객체에서 비슷한 역할을 하는 속성, 메서드를 캡슐처럼 한 클래스에 담는 것을 의미한다.
- 캡슐화된 객체의 세부 내용이 외부에 은폐(정보 은닉)되어, 변경이 발생할 때 오류의 파급 효과가 적다.
- 캡슐화된 객체들은 재사용이 용이하다.
- 객체들 간의 메시지를 주고받을 때 각 개체의 세부 내용은 알 필요가 없으므로 인터페이스가 단순해지고, 객체 간의 결합도가 낮아진다.
캡슐화에서 가장 중요한 개념은 정보은닉이다.
정보은닉은 말 그대로 '정보를 숨긴다.'라는 것인데, 객체의 구체적인 정보(변수, 메서드)를 외부에 노출시키지 않고 접근할 수 없게 보호하는 방법이다.
캡슐화를 통해 정보를 은닉하면 그 정보는 오직 객체 내의 함수 내부에서만 접근이 가능해진다.
정보은닉 정리
1. 각 객체의 수정이 다른 객체에게 주는 영향을 최소화
2. 외부 객체가 특정 객체의 데이터와 함수를 직접 접근하여 사용하거나 변경하지 못하므로 유지보수와 소프트웨어 확장 시 오류를 최소화할 수 있다.
2. 추상화(Abstraction)
추상화는 불필요한 부분을 생략하고 객체의 속성 중 가장 중요한 것에만 중점을 두어 개략화하는 것, 즉 모델화를 하는 것이다.
객체들은 구체적인 값이 부여되어 실제로 만들어지는 개념이지만, 클래스는 객체들이 가져야 할 특성이나 기능들을 정의해둔 추상적인 개념이다.
추상화는 객체들의 공통된 특징들만 뽑아내는 기법이라고도 할 수 있다.
3. 상속(Inheritance)
상속은 부모 클래스의 특징을 자식 클래스가 물려받는 것이다.
상속이란 상위 개념의 특징이 하위 개념이 물려받는 것을 말한다.
하나의 클래스가 가지고 있는 특징(데이터와 함수)들을 그대로 다른 필요한 클래스에 물려주고자 할 때 상속 성의 특징을 사용한다.
상속은 코드를 재사용할 수 있기 때문에 중복을 제거할 수 있다는 장점도 있다.
4. 다형성(Polymorphism)
다형성은 '다양한 형태'를 가지는 특성(?)을 말한다.
다형성은 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질을 말한다.
같은 타입이라는 것은 부모 클래스가 같다는 의미이다.
같은 부모 클래스 타입으로 선언되었지만, 하위 클래스가 모두 다르다는 것을 나타낸다.
예를 들어 시계는 건전지 타입으로 에너자이저, 듀라셀, 로켓을 사용하지만 각 건전지의 성능은 다르게 나온다.(다형성)
동일 건전지이지만, 형태나 성질이 다르다는 "다형성"의 사전적 의미와 매우 유사하다고 느낄 수 있다.
// Battery.js [상속의 개념과 다형성의 개념이 다 들어가 있다.]
class Battery{
constructor(name){
this.Rocket
this.Duracell
this.Energizer
}
getName(){
return this.Rocket;
}
makeNoise() {
console.log('ES6');
}
}
// Rocket.js
class Rocket extends Battery {
constructor(){
super();
}
}
// Duracell.js
class Duracell extends Battery {
constructor(){
super();
}
// Override
makeNoise() {
console.log('Duracell King');
}
}
// Energizer.js
class Energizer extends Battery {
constructor(){
super();
this.Rocket
this.Duracell
this.Energizer
}
}
// new 키워드를 통해 인스턴스를 불러오거나 만든다.
let battery1 = new Rocket();
let battery2 = new Duracell();
let battery3 = new Energizer();
console.log(battery1.getName);
console.log(battery1, battery2, battery3) // battery1, 2, 3의 타입은 모두 Battery이지만 해당된 객체는 하위 클래스 객체들이다.
console.log(battery2.getName)
battery1.makeNoise();
battery2.makeNoise();
일단 예제에 대한 내 생각을 설명을 해보면....
extends 키워드를 사용해 Rocket, Duracell, Energizer 클래스가 Battery 클래스를 상속했다.
이제 Battery 클래스는 3개의 클래스의 superclass가 되었고, 3가지 클래스는 Battery 클래스의 subclass가 되었다.
3가지 클래스는 Battery 클래스가 가지고 있는 this.Rocket과 getName()을 똑같이 갖는다.
subclass의 constructor에는 super()를 넣어 superclass의 constructor를 호출할 수도 있다.
super는 하위 클래스에서 상위클래스를 수정할 때 주로 사용된다.
- super()시 부모 클래스의 생성자 호출. 필요한 인자를 넘겨줘야한다.
- super. 사용시 부모 클래스의 속성값에 접근하는 용도로 사용한다.
만약 super()를 사용하지않는다면?
1. 부모 클래스에서 기능을 추가하고 싶을 때 필요한 코드를 자식 클래스에서 중복 작성해야한다.
2. 자식 클래스에서 부모 클래스의 속성값에도 접근하지 못한다.
그래서 super()를 사용하는 것을 권장한다.
다형성이란, 동일한 타입을 가진 여러 객체가 같은 속성을 가지는 성질을 일컫는 말이다.
위 예제에는 상위 클래스 Battery와, 그를 상속하는 하위 클래스 Rocket, Duracell, Energizer 3개가 있다.
✏️Overriding(오버라이딩) : 부모클래스 메서드를 자식 클래스에서 재정의하는 것
✏️Overloading(오버로딩) : 같은 이름으로 다양한 매개변수, 리턴타입의 메소드를 여러개 정의하는 것
먼저 battery1, 2, 3의 타입은 모두 Battery이지만, 할당된 객체는 하위 클래스 객체들이다.
하위 클래스들은 모두 Battery를 상속받고 있기 때문에 자동으로 캐스팅할 수 있어 에러가 발생하지 않는다.(Auto Casting)
정리
✏️객체란?
- 대상을 나타내는 단어
- 객체 = 속성(특징, 상태) + 행동(동작, 기능)
- 객체의 속성은 변수로, 객체의 행동은 함수로 구현한다.
✏️객체 지향 프로그래밍
- 객체들이 상호작용하는 과정을 프로그래밍하는 것
✏️클래스
- 클래스 = 객체의 속성과 행동을 코드로 적어둔 곳
- 클래스의 변수에 구체적인 값을 할당하면 객체를 정의할 수 있다.
✏️객체지향 프로그래밍 특징 4가지
- 캡슐화 (Encapsulation) : 한 객체에서 비슷한 역할을 하는 속성, 메서드를 캡슐처럼 한 곳(클래스)에 담는 것
- 추상화(Abstraction) : 복잡한 문제를 단순화 ex) 전화기
- 상속(Inheritance) : 부모 클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게 한다.(일부 변경, 추가 가능)
- 다형성(Polymorphism) : 다양한 형태를 가지는 특성 (위에 예시를 봐주세요, 오버라이딩? 오버로딩?) ex) 배터리