클래스와 인스턴스
클래스
- 객체 지향을 지원하는 대부분의 프로그래밍 언어에서는 객체 구현을 위해 클래스(class)를 지원한다.
- 예를 들어 파이썬에는 다음처럼
class로 객체를 표현할 수 있다.
1 | |
인스턴스
- 그리고 이 클래스를 다음처럼 하나의 인스턴스로 만들 수 있다.
- 이를 “클래스를 인스턴스화 한다”고 한다.
1 | |
user_1과user_2는 같은 클래스로부터 만들어졌지만, 서로 다른 인스턴스이다.- 즉, 이 둘은 같은 형태(클래스)를 취하고 있지만, 각자 다른 메모리 공간에 존재하고, 각자 독립된 내용을 담을 수 있다.
1 | |
속성과 메서드
속성
- 클래스의 속성(attribute)은 클래스 내에 담기는 데이터들을 말하며 멤버 변수라고도 이야기한다.
- 클래스 속성은 크게 클래스 변수와 인스턴스 변수로 나눠볼 수 있다.
인스턴스 변수
- 인스턴스 변수는 인스턴스별로 독립적으로 가질 수 있는 값이다.
- 다음은 인스턴스 변수를 정의한 예시이다.
1 | |
- 이렇게 정의한 인스턴스 변수는 다음처럼 인스턴스별로 다르게 설정할 수 있다.
1 | |
- 인스턴스 변수는 다음과 같이 접근한다.
1 | |
클래스 변수
- 클래스 변수는 클래스 자체에 정의되는 변수이다.
- 같은 클래스의 인스턴스들은 같은 클래스 변수값을 가지게 된다.
1 | |
- 클래스 변수 역시 인스턴스 변수와 같은 방식으로 접근한다.
1 | |
- 인스턴스별로 독립된 메모리 공간을 가지는 인스턴스 변수와 달리, 클래스 변수는 같은 클래스의 인스턴스들이 공유한다.
메서드
- 메서드는 클래스가 가지고 있는 함수이자 객체가 할 수 있는 행위를 말한다.
- 메서드는 크게 공개형(public) 메서드와 비공개형(private) 메서드로 나눠볼 수 있다.
공개형 메서드
- 공개형 메서드는 이 클래스가 외부에 제공해주는 메서드이다.
- 다음 예시에서
work()는 공개형 메서드이다.
1 | |
- 이렇게 정의된 공개형 메서드는 클래스 외부에서 다음처럼 사용할 수 있다.
1 | |
비공개형 메서드
- 비공개형 메서드는 클래스 내부에서만 사용하는 메서드이다.
- 다음 예시에서
_get_work_type()메서드는 비공개형 메서드이다. - 파이썬의 경우 자바와 다르게 접근 제어자 문법이 없다.
- 다만 변수나 메서드 이름 앞에
_(underscore)를 붙임으로써 비공개 변수, 메서드임을 명시하는 게 관습이다. - (참고)
__를 두개 붙여 조금 더 private하게 변수나 메소드를 관리할 수 있는name mangling도 있다.
1 | |
- 비공개형 메서드는 외부에서 접근하지 못하거나, 할 수 있더라도 하지 않는 게 관습이다.
- 위의 예시처럼 비공개형 메서드는 공개형 메서드의 로직의 일부를 내부적으로 재사용하고, 의미를 분리하기 위해 사용하기 위한 목적으로 사용하곤 한다.
접근 제어자
- 접근 제어자는 변수 혹은 함수(메서드)에 대한 접근을 제어하는 역할을 한다.
- 예를 들면 자바와 같은 객체 지향 언어에는
private,protected,private과 같은 접근 제어자가 있다. private으로 표시된 변수나 메서드는 클래스 내부에서만 접근할 수 있다.- 클래스 외부에서 접근하려고 할 시, 컴파일 시점에 에러를 뱉는다.
- 객체 지향 언어에서는 보통 이런 제어자를 통해 공개형, 비공개형에 대한 표시를 아주 명확히 하곤 한다.
상속
- 객체 지향 프로그래밍 언어들은 대부분 클래스 문법과 상속을 제공한다.
- 상속(inheritance)은 이전에 정의한 클래스의 데이터와 메서드를 그대로 내려받는 기능이다.
- 이때 상속해주는 클래스를 “부모 클래스” 혹은 “기반 클래스”라고 하며, 상속받는 클래스를 “자식 클래스” 혹은 “파생 클래스”라고 한다.
- 다음은 파이썬에서 상속의 예시이다.
1 | |
DataEnginner,ProjectManager클래스가Job클래스를 상속받았다.Job클래스는 부모 클래스,DataEnginner,ProjectManager클래스는 자식 클래스가 된다.DataEnginner,ProjectManager클래스는Job을 상속받았으므로,Job클래스에서 정의한do(self)메서드를 그대로 사용할 수 있다.
1 | |
인터페이스
인터페이스
- 인터페이스(interface)는 객체의 행위(메서드)만을 정의한 것으로, 구체적으로는 클래스의 메서드의 명세라고 볼 수 있다.
- 파이썬에서는 인터페이스가 따로 없어 추상클래스로 인터페이스를 구현하였다.
1 | |
구현체
- 인터페이스는 보통 그대로 인스턴스화 할 수 없다.
- 예를 들어 다음 코드는 에러를 뱉는다.
1 | |
- 인터페이스는 객체의 뼈대만을 담당하고 있다.
- 실제로는 다음처럼 인터페이스 객체를 상속받는 구현 클래스도 구현해야한다.
1 | |
인터페이스 사용 이유
- 우리가 은행에 가서 은행원에게 돈을 입금해달라고 가정해본다.
- 우리는 은행원이 우리에게 돈을 입금해주는 행위을 제공하고 있다.
- 하지만 구체적으로 이 은행원이 어떻게 돈을 입금해주는 지 관심이 없다.
- 그걸 몰라도 우리는 입금해달라고 요청하면 입금이 잘 될거라는 것을 알고있고 신뢰하기 때문이다.
- 마찬가지로 위에서 정의한
Job을 외부에서 사용하는 코드(보통 클라이언트라고 한다)는Job이 어떤 행위를 제공하는 지(Job의 퍼블릭 메서드)에 주로 관심이 있다. Job이 어떤 데이터를 들고있으며, 행위을 하기 위해 구체적으로 어떤 알고리즘을 가지고 있는지 클라이언트 입장에서는 중요하지 않다.- 우리는
Job이 어떤 행위를 제공하는지 보려면 그저Job이라고 하는 인터페이스만 보면된다. - 그렇게 되면 자연스럽게 구현(저수준 코드)을 의존하기 보단 인터페이스(고수준)에 의존하게 되어 결합도를 낮출 수 있다.(= 다형성)
- 또한
DataEngineer(Job),ProjectManager(Job)와 같은 구현 클래스가Job추상 클래스를 상속받는 것을 통해 이 두 클래스가 같은 개념 아래 묶여있는 것을 알 수 있다. - 즉, 구현 클래스 간의 관계를 파악하기도 쉬워진다.