시작하기에 앞서
- 본 글은 java 국비지원 과정을 듣고 있는 학생이 쓴 글로, 비숙련자가 공부한 내용을 바탕으로 정리한 글이기 때문에 내용에 다소간에 오류가 있을 수 있습니다.
- 해당 문법의 개념에 대해 설명하고 있기 때문에 설명하는 텍스트가 상당히 많습니다! 기술적인 정보보다는 개념을 이해하고자 적은 텍스트 기반의 글임을 알립니다!
자바는 객체 지향 프로그래밍 언어이다. 객체 지향 특징을 가진 언어로써 자바는 다음과 같은 특징을 갖는다.
- 추상화(abstraction) - 지하철 노선도와 같이 특정 필요한 정보만을 중심으로 실제를 간소화 한 것
- 캡슐화(encapsulation) - 보안 등의 이유로 데이터 혹은 기능을 하나로 묶어 관리하는 것
- 상속성(inheritance) - 하나의 클래스가 가진 특징을 다른 클래스가 물려받는 것
- 다형성(polymorphism) - 오버로딩(Overloading)과 오버라이딩(Overriding)
그렇다면 객체란 무엇일까? 사실 위에 기술되어 있는 일련의 '객체 지향의 특징'을 이해하기 위해서는 객체가 무엇인지 알아야 하는데 지금부터 본격적으로 객체가 무엇인지, 그리고 그 객체를 정의하는 툴로써의 클래스가 무엇인지 알아보도록 하자.
객체(Object)와 클래스(Class)
c언어와 같은 절차 지향 언어에서는 자바에서 '메소드'라 불리는 '함수'를 이용해 프로그래밍을 진행한다. 함수 하나하나를 전체 코드를 이루는 부품으로 삼아, 그 부품을 결합하고 조합해서 하나의 거대한 프로그램을 만드는 것이다. 즉, 절차 지향의 언어에서는 그 언어를 구성하는 가장 중추적인 위치에 함수가 존재한다.
자바와 같은 객체 지향 언어에서는 이러한 역할을 클래스가 수행한다. 클래스는 객체를 만들기 위해 객체의 속성(state)과 행동(behavior)을 기술해놓은 일종의 객체 설계도로 인스턴스 변수, 메소드, 그리고 생성자로 구성된다.
클래스(Class)의 구성요소
- 인스턴스 변수(Member Field)
- 메소드(Member Method)
- 생성자(Constructor)
말이 조금 어려운 것 같으니 쉽게 예를 들어보자.
여러분들은 서울에 있는 어떤 부지에 새로운 빌딩을 건축하기 위해, 지금 막 모델하우스에 건물을 보러 이곳에 왔다. 한참을 구경하다 마음에 드는 건물이 있어서 해당 건물에 대해 알아보니 이 건물을 짓기 위해서는 세가지 인테리어 옵션 중 하나를 선택해야 한다는 것을 알게되었다. 옵션 A, B, C는 전체적인 구조면에서 매우 비슷하지만 내부 인테리어나 외관에 약간의 차이가 있다고 한다. 어떤 옵션을 선택해야 할까?
한 개의 건물, 세 개의 옵션
앞의 예를 통해 우리는 클래스와 객체를 어떻게 이해할 수 있을까? 우선, 여러분은 마음에 드는 '한 개'의 건물을 발견했다. 그리고 그 건물을 구체화할 수 있는 '세 개'의 옵션을 마주했다.
클래스는 위의 비유에서 '한 개'의 건물에 대응될 수 있다. 대표적인 건물, 즉 옵션으로 구체화되는 실제 분양 건물의 모체이자 분양되는 모든 건물들이 공유하는 특징을 정의하는 대상. 클래스는 모든 객체에 대해 보편적인 특징을 지닌다.
객체는 위의 비유에서 '세 개'의 옵션에 대응될 수 있다. 건물 틀로 정의된 대표적인 건물에 살을 입혀 실제로 사람이 살 수 있는 것들을 갖춘 것. 클래스에 비해 다양한 특징을 지니며 다른 객체들과 구별되는 자신만의 특징을 갖는다. 객체는 클래스에서 특수한 형태를 구현한 것이라고 표현할 수 있다.
비유가 너무 난해하고 어려울지도 모르겠다. 만약 클래스가 무엇인지, 객체가 무엇인지 모르겠다면, 클래스는 '어떤 것의 원형', 객체는 '그것을 재사용하기 위해 복사한 무언가'라고 생각해도 크게 무리가 있지는 않을 것 같다.
그럼, 클래스는 어떻게 객체를 만들까? 객체는 클래스를 통해 인스턴스를 만들 때 생성된다. 클래스를 통해 인스턴스를 만드는 방법은 다음 장에서 살펴보자.
인스턴스(Instance) 만들기
클래스를 인스턴스로 바꾸는 과정은 총 3단계에 걸쳐 진행된다. 다음의 코드는 클래스를 인스턴스화하는 일반적인 방법이다.
className varName = new className();
// ex)
Car myCar = new Car();
각각의 요소는 다음과 같은 특징을 갖는다.
- (가장 왼쪽, className) 클래스 이름 - varName의 참조형 데이터타입으로 클래스를 갖는다는 것을 의미한다.
- (두번째 왼쪽, varName) 변수명 - 레퍼런스 변수값으로, heap 메모리상에 있는 인스턴스 데이터값에 대한 접근에 이 변수명을 사용하겠다는 것을 의미한다.
- (세번째 왼쪽) new - 메모리상에 인스턴스의 공간을 생성한다. (객체 생성)
- (마지막 오른쪽, className) 생성자 - 3번에 의해 생성된 객체의 값을 초기화한다. (기본값 정수 - 0, 문자열 - null)
이렇게 생성된 인스턴스는 heap 메모리상에 위치하게 되고, 이로써 클래스와 연결되지 않고 독립적으로 행동할 수 있는 존재가 된다(클래스는 data 메모리상에 위치한다). 다만 클래스상에 static 값을 가진 요소가 존재할 경우 인스턴스의 해당 요소값을 변경하면 클래스의 값도 변경되기 때문에 주의가 필요하다. (뒤에 따로 살펴보자.)
생성자(Constructor)
생성자는 클래스를 언급할 때 가장 중요한 하위 주제중 하나로 클래스가 인스턴스를 생성할 때 인스턴스의 값을 초기화하는 역할을 수행한다. 문법적으로 메소드와 유사한 형태를 띄고 있는데 일반적인 메소드와는 달리 리턴형 타입을 명시하지 않는다는 특징을 갖는다. 생성자는 클래스의 이름과 반드시 일치해야 하고, 한 개의 클래스에는 적어도 한 개 이상의 생성자가 존재해야 한다. 사용자가 클래스에서 생성자를 만들지 않을 때는 컴파일러가 자동으로 디폴트 생성자를 만들어준다.
생성자에 대한 문법은 다음과 같다.
class ClassName {
// 생성자
ClassName() {
}
}
생성자는
- 인자(argument)를 가지지 않는 생성자와
- 인자를 가지는 생성자
로 나눌 수 있고, 생성자는 메소드와 마찬가지로 오버로딩(overloading)이 허용된다.
오버로딩(Overloading)
같은 이름의 메소드를 한 개의 클래스에서 두 개 이상 사용하는 것을 말한다. 완전히 같아서는 안되고, 매개변수에서 차이가 있어야만 한다.
ex) 허용되지 않는 경우
class Class {
// 메소드 하나
void Method() { ... }
// 메소드 둘 (에러 발생)
void Method() { ... }
}
ex) 허용되는 경우
class Class {
//메소드 하나
void method() { ... }
//메소드 둘 (오버로딩)
void method(int a) { ... }
//메소드 셋 (오버로딩)
void method(int a, int b) { ... }
}
static : 클래스 변수, 클래스 메소드
마지막으로 살펴볼 부분은 static 키워드이다. static 키워드는 쉽게 생각해서 클래스의 것이라고 생각하면 될 것 같다. 따라서 객체화될 수 없는 요소이고(맞는 표현인지 모르겠다), 인스턴스가 사용할 수 있기는 하지만 소속이 클래스에 있기 때문에 static이 붙은 데이터를 특정 인스턴스에서 독립적으로 변경할 수 없다. (그렇다고 인스턴스에서 해당값을 변경할 수 없는 것은 아닌데, 인스턴스에서 해당 값을 변경하면 그에 따라 클래스의 값이 곧바로 변경된다. 그럼 모든 인스턴스의 해당 값도 같이 변경된다.) 생성자와 묶어서, 어떤 클래스에 대한 인스턴스를 하나 만들 때마다 특정 static 변수의 값을 하나씩 올린다고 가정한다면, 이를 통해 만들어진 인스턴수의 수를 계산할 수 있게 되고 마찬가지의 원리로 각각의 인스턴스에 특정한 id값을 부여할 수도 있다. (응용적인 부분)
아래의 사진은 생활코딩의 자바 인문 수업 - 객체 지향 프로그래밍 - static 강좌 안에 있는 도식으로 이 개념에 대해 아주 잘 표현한 도식인 것 같아서 가져왔그려봤다. 아무도 이해할 수 없을 것 같은 복잡한 그림이 되어버렸는데 static에 대해 궁금하신 분들은 생활코딩의 수업을 한번 들어봐도 좋을 것 같다.
'JAVA' 카테고리의 다른 글
컬렉션 프레임워크(collection framework) 상속 관계 도표 사이트 (0) | 2021.09.23 |
---|---|
JAVA 문법 : 다형성(Polymorphism) (0) | 2021.09.15 |
2021. 08. 07 Java 연습 문제 풀기 & 모르는 문제 (4) | 2021.08.07 |
Java로 복리 계산기 만들기 (0) | 2021.08.06 |
2021. 08. 04. JAVA 객체지향과 리펙토링 실습 (0) | 2021.08.04 |