클래스가 가져야 할 구성 멤버

  1. 필드(Field) : 객체의 데이터가 저장되는 곳
  2. 생성자(Constructor) : 객체 생성 시 초기화 역할 담당
  3. 메소드(Method) : 객체의 동작에 해당하는 실행 블록

 

[필드]

객체의 고유 데이터, 부품 객체, 상태 정보를 저장하는 곳이다.
선언 형태는 변수와 비슷하지만 필드를 변수라고 부르지 않는다. 

변수는 생성자와 메소드 내에서만 사용되고 생성자와 메소드가 종료되면 자동 소멸되지만
필드는 생성자와 메소드 전체에서 사용되며 객체가 소멸되지 않는 한 객체와 함께 존재한다.

 

[생성자]

new 연산자로 호출되는 특별한 {} 블록이다.

생성자는 객체 생성 시 초기화를 담당하는데, 
필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 한다.

생성자는 메소드와 비슷하게 생겼지만, 클래스 이름으로 되어 있고 리턴 타입이 없다.

 

[메소드]

객체의 동작에 해당하는 {} 블록이다. 

이 때 {} 블록의 이름이 메소드 이름이다.

메소드를 호출하게 되면 { ... } 안의 모든 코드들이 일괄적으로 실행된다.

메소드는 필드를 읽고 수정하는 역할도 하지만 다른 객체를 생성해서 다양한 기능을 수행한다.
또한 객체 간의 데이터 전달의 수단으로도 사용되며 외부로부터 매개값을 받을 수 있고 
실행 후 어떤 값을 리턴할 수도 있다. 

 


필드

객체의 고유 데이터, 객체가 가져야 할 부품, 객체의 현재 상태 데이터를 저장하는 곳이다.

오늘도 많이 본 자동차를 예로 들어보자.

 

자동차 객체   자동차 클래스 | public class Car { ... }
[고유 데이터] 제작회사 고유 데이터
클래스
String company;
모델 String model;
색깔 String color;
최고속도 int maxSpeed;
[상태] 현재속도 상태
클래스
int speed;
엔진 회전 수 int rpm;
[부품] 차체 부품
클래스
Body body;
엔진 Engine engine;
타이어 Tire tire;

 

필드의 초기값은 필드 선언 시 주어질 수도 있고 생략될 수도 있다.

위의 표에 나온 '자동차 클래스'는 생략된 케이스이다.

 

[필드 선언 예시]

public class Car {

// 필드 초기값 선언
String company = "현대자동차";
String model = "그랜저";
int maxSpeed = 300;

// 필드 초기값 생략
int productionYear;
int currentSpeed;
boolean engineStart;

}

 

[필드 타입별 초기값]

분류 데이터 타입 초기값
기본 정수  - byte
 - char
 - short
 - int
 - long
 - 0
 - ' ' (공백)
 - 0
 - 0
 - 0L
int와 long의 차이:
L의 유무
실수  - float
 - double
 - 0.0F
 - 0.0
float과 double의 차이:
F의 유무
논리  - boolean false
참조  - 배열
 - 클래스 (String 포함)
 - 인터페이스
 - null
 - null
 - null

 


생성자

new 연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당한다.

객체 초기화란, 필드 초기화 또는 메소드를 호출해서 객체를 사용할 준비를 하는 것을 말한다.

 

생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없다.

 

[기본 생성자 (디폴트 생성자, default Constructor)]

모든 클래스는 생성자가 반드시 존재하며, 하나 이상을 가질 수 있다.

+++

[오답노트]

프로그래밍 언어 활용 시험 5번문제 - 디폴트 생성자를 생성하시오. 

기본 생성자는 매개변수를 하나도 가지지 않으며, 어떤 명령어도 포함하지 않는다.
문법으로는 클래스명을 따 온다.

클래스명() {}

+++

클래스가 public class로 선언되면 기본생성자에서도 public이 붙지만

클래스가 public 없이 선언되면 기본생성자에도 public이 붙지 않는다.

 

[public] 클래스() { ... }

 

[생성자 선언]

// 생성자블록
클래스(매개변수선언) {
	// 객체의 초기화 코드
}

// 객체의 초기화 코드에는 필드에 초기값을 작성하거나 메소드를 호출하여 객체 사용 전 필요한 준비를 한다.

매개변수선언은 생략할 수도 있고, 여러 개를 선언할 수도 있다. 

매개변수는 new 연산자를 통해 외부의 값을 생성자 블록 내부로 전달하는 역할을 한다.

Car myCar = new Car("그랜저", "검정", 300);

========

public class Car {
// 생성자
Car(String model, String color, int maxSpeed) { ... }
}

Car 클래스에 생성자 선언이 있기 때문에

기본생성자 [Car()]를 호출해서 객체를 생성할 수 없고

Car(String color, int cc)를 호출해서 객체를 생성해야 한다.

 

[필드 초기화]

클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동설정된다.

이때 만약 다른 값으로 주고 싶다면 '필드를 선언할 때 초기값을 주는 방법'과 '생성자에서 초기값을 주는 방법'이 있다.

 

 

(1) 필드 선언 시 부여 (String nation;)

동일한 클래스로부터 생성되는 객체들은 모두 같은 데이터를 갖게 된다.

객체 생성 후 변경할 수 있지만, 객체 생성 시점에는 필드의 값이 모두 같다.

 

(2) 생성자 초기값 부여 (String name; / String birth;)

객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화되어야 할 때 사용한다.

name과 ssn의 필드값은 클래스를 작성할 때 초기값을 줄 수 없고 객체 생성 시점에 다양한 값을 가져야 한다.

 

11번째 줄을 보면 String n, s를 사용한 것을 볼 수 있다.

하지만 실제 코드를 작성할 때는 확 줄여서 그 의미를 모르게 하는 것보다 필드명을 그대로 사용함으로 

매개변수가 무엇을 의미한 것인지를 표시해주는 것을 추천한다.

 

우리가 스스로를 '나'라고 칭하듯이 객체가 객체 자신을 스스로 칭하는 것을 'this'라고 한다.

 

"this.필드"는 this라는 참조 변수로 필드를 사용하는 것과 동일하다. 

 

this.name = name; 에서

앞의 name은 필드이고, 뒤의 name은 매개변수이다. 

 

객체의 필드는 하나가 아니라 여러개 가 있고, 이 필드들을 모두 생성자에서 초기화한다면

생성자의 매개 변수의 수는 객체의 필드 수만큼 선언되어야 한다. 

 

하지만 실제로는 중요 몇 개 필드만 매개 변수를 통해 초기화되고 나머지는 필드 선언 시 초기화하거나

생성자 내부에서 임의의 값 또는 계산된 값으로 초기화한다. 

 

[생성자 오버로딩]

Car 객체를 생성할 때 외부에서 제공되는 데이터가 없다면 기본 생성자로 Car 객체를 생성해야 하고

외부에서 model 데이터가 제공되거나 model, color가 제공될 경우에도 Car 객체를 생성할 수 있어야 한다.

 

이에 자바는 다양한 방법으로 객체를 생성할 수 있도록 생성자 오버로딩(Overloading)을 제공한다.

 

'오버로딩'이란, 매개 변수를 달리하는 생성자를 여러 개 선언하는 것을 말한다. 

 

 

생성자 오버로딩

 

주의할 점이 있다면, 아래와 같이 다른 건 다 같으나 순서가 바뀐 것은 오버로딩이라고 볼 수 없다.

생성자 오버로딩 시 주의할 점

 

생성자가 오버로딩 되어 있을 경우 new 연산자로 생성자를 호출할 때 제공되는 

매개값의 타입과 수에 의해 호출될 생성자가 결정된다. 

 

 

생성자 선택 예시

 

[생성자 호출 this()]

생성자 오버로딩이 많아질 경우 생성자 간의 중복된 코드가 발생할 수 있다.

이런 현상은 매개 변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자에서 많이 목격된다.

이 때 필드 초기화 내용은 한 생성자에만 집중적으로 작성하고 나머지에서는 초기화 내용을 가지고 있는 생성자 호출방법을 사용한다.

 

다음은 생성자에서 다른 생성자를 호출할 때에 쓰이는 코드와 사용방법이다.

클래스 ( [매개변수선언] ) {
    this( 매개변수, ..., 값, ...); 	// 클래스의 다른 생성자 호출
    실행문;
}

this() 는 자신의 다른 생성자를 호출하는 코드로 반드시 생성자의 첫줄에서만 허용된다. 

this() 다음에는 추가적인 실행문들이 올 수 있다. 

--> 호출되는 생성자의 실행이 끝나면 원래 생성자로 돌아와서 다음 실행문을 진행한다는 뜻이다. 

 

아래는 중복코드와 변화된 코드이다.

생성자 호출 this()

왼쪽의 CarThis 클래스를 적으면서 느낀 점은 이걸 이렇게 쓰기는 할까? 라는 의문인데 

아직 이렇다 할 경험이 없으니 일단 적고 넘어가겠다. 

 

아무튼 왼쪽의 CarThis를 오른쪽의 CarThis2로 변화시켜 보았다. 확실히 줄은 줄었으나

'굳이?'라는 생각은 사라지지 않는다.


이 글을 적으면서 느끼는 것은 객체에 관한 것은 직접 만들어봐야 는다는 것이다.

(뭐든 이렇지 않겠나마는...)

 

오늘은 책에 적힌 자동차로 공부를 하였다면 

내일은 우리가 하루도 빠짐없이 보는 스마트폰을 예제로 사용할 수 있고 

그 다음날은 또 다른 것으로 예를 들어볼 수 있을 것이다. 

 

결론:

공부도 당연하지만 직접 만들고 고민해보는 시간을 가지자.

지금 머리가 아파야 훗날이 편하다. (아마도)

+ Recent posts