본문 바로가기

JAVA

자바 기초부터 차근차근...(8)

※ Chapter07 클래스와 인스턴스  
※ 본문은 윤성우의 열혈JAVA를 정리한 글입니다. 
※ 문제가 될시 비공개 처리하겠습니다.


§클래스의 정의와 인스턴스의 생성

 

이번 챕터에서는 클래스에 대해 배운다.

 

■클래스(Class) = 데이터(Data) + 메소드(Method)

 

데이터 - 프로그램상에서 유지하고 관리해야 할 데이터

기능 - 데이터를 처리하고 조작하는 기능

 

이 중에서 데이터는 '변수의 선언'을 통해 유지 및 관리가 된다.

변수에 저장된 데이터는 '메소드의 호출'을 통해 처리가 된다.

 

다음예제를 살펴보자. (은행 계좌를 간단히 표현한 것)

각각의 메소드 내에서 접근하는 변수 balance는 2행에서 선언되었다.

이것은 '전역변수' 라고 하는데 자세한건 다시 배우도록 한다.

 

우선 지금 알아보고자 하는 것을 알아보자.

 

데이터 - 변수 balance는 프로그램상에서의 '데이터'이다.

기능 - 메소드 deposit, withdraw, checkMyBalance는 프로그램상에서의 '기능'이다.

 

"변수 balance는 메소드 deposit, withdraw, checkMyBalace와 긴밀히 연관되어 있다." 라고 볼 수 있다.

 

이렇듯, 연관있는 변수와 메소드를 묶기 위해 '클래스'라는 것이 존재한다.

클래스를 이용하면 다음과 같이 변수 balance 그리고 모든 연관 메소드를 하나로 묶을 수 있다.

 

class BankAccount {

     int balance = 0;

     public int deposit(int amount) {

          balance -= amount;

          return balance;

     }

...

이는 BankAccount 클래스의 정의라고 볼 수 있다.

 

■클래스의 구성과 인스턴스화

 

위에서 정의한 클래스 BanckAccount의 정의를 큰 틀에서 보면 다음과 같다.

 

인스턴스 변수 =>  int balance = 0;

인스턴스 메소드 => public int deposit(int amount) ...

 

인스턴스 변수란 클래스 내에 선언된 변수를 의미하고,

인스턴스 메소드란 클래스 내에 정의된 메소드를 의미한다.

 

이를 응용하여 예제를 보기에 앞서, 클래스 정의의 본질을 설명한다.

 

"클래스의 정으는 틀을 구성하는 것과 같다."

클래스가 정의되었다고 해서 그 안에 위치한 변수나 메소드를 사용할 수 있는 것은 아니다.

틀을 이용해서 다음과 같이 '인스턴스'라는 것을 찍어 내야 사용이 가능하다.

new BankAccount(); // 클래스 BankAccount의 인스턴스화

물론 둘, 혹은 그 이상도 만들 수 있다.

 

그런데, 이렇게 메모리상에 인스턴스를 만들기만 해서는 사용할 수 없다.

만들어진 인스턴스를 참조할 수 있는 무엇인가가 필요하다. 그것을 '참조변수' 라고 한다.

BankAccount myAcnt; // 참조변수 myAcnt의 선언

 

즉, 다음과 같이 참조변수를 선언하고 이를 통해서 새로 생성되는 인스턴스를 가리키게 할 수 있다.

BankAccount myAcnt1; // 참조변수 myAcnt1 선언

BankAccount myAcnt2; // 참조변수 myAcnt2 선언

 

myAcnt1 = new BankAccount();

myAcnt2 = new BankAccount();

//참조변수가 새로 생성되는 인스턴스를 가리킴

 

여기서 new를 통해서 인스턴스를 생성하면 생성된 인스턴스의 주소값이 반환된다.

즉, 참조변수에는 생성된 인스턴스의 주소값이 저장되는 셈이다.

다음과 같이 한 문장으로 묶을 수도 있다.

BankAccount myAcnt1 = new BankAccount();

 

참조변수를 통해 인스턴스 메소드를 호출하는 방법은 다음과 같다.

 

myAcnt1.deposit(1000); << 이런식으로 인스턴스 메소드를 호출함.

 

이제 예제를 보면서 이해하고 넘어가보자.

지금까지 이야기한 것들을 넣어놓은 예제이다.

 

 

■ 참조변수의 특성

 

참조변수도 변수이다.

따라서 참조변수도 다음과 같이 참조하는 인스턴스를 바꿀 수 있다.

BankAccount yoon = new BankAccount();

...

yoon = new BankAccount();

...

 

다음과 같이 참조변수가 지니고 있는 값을 다른 참조변수에 대입하여

하나의 인스턴스를 둘 이상의 참조변수가 동시에 참조하는 것도 가능하다.

BankAccount ref1 = new BankAccount();

BankAccount ref2 = ref1;

...

 

■ 참조변수의 매개변수 선언

 

메소드를 호출할 때 값을 전달할 수 있고, 이 값은 매개변수에 저장된다.

예제를 보면서 확인하고 넘어가자.

참조변수가 인스턴스와 관계를 끊고 아무런 인스턴스도 참조하지 않도록

하기 위해서는 null을 대입하면 된다.

ref = null;

 

§ 생성자(Constructor)와 String 클래스의 소개

 

■String 클래스에 대한 첫 소개

 

문자열은 큰따옴표로 묶어서 표현함을 이미 우리는 알고 있다.

문자열은 다음과 같이 참조변수를 선언해서 참조할 수도 있다.

String myName = " Cood Ma"

 

String은 자바에서 제공하는 클래스의 이름인데 이러한 내용은 이후에 별도로 설명을 한다.

 

다음예제를 보자.

위의 예제를 통해 두가지 사실은 다음과 같다.

- 문자열을 메소드의 인자로 전달할 수 있다.

- 매개변수로 String형 참조변수를 선언하여 문자열을 인자로 전달받을 수 있다.

 

 

■ 인스턴스를 구분할 수 있는 유일한 정보를 갖게 하자. (고유정보)

 

앞서 정의한 BankAccount 클래스를 다시 보면,

인스턴스를 구분할 수 있는 정보가 빠져있다. 따라서 누구의 계좌인지 구분할 수 있도록 해야한다.

 

이를 반영하여 BankAccount 클래스를 수정한 결과는 다음과 같다.

initAccount 메소드는 다음과 같은 부분에서 다른 메소드들과 성격상 구분이 된다.

- 인스턴스의 초기화를 위한 메소드이다.

- 때문에 인스턴스 생성 시 반드시 한번 호출해서 초기화를 진행해야 한다.

 

 

그러나, '생성자(Constructor)'를 이용하면 초기화를 진행할 수도 있다.

생성자는 인스턴스 생성 과정에서 초기화를 위해 자동으로 호출되는 메소드이다.

 

 

■생성자(Constructor)

생성자가 되기 위한 조건은 다음과 같다.

- 생성자의 이름은 클래스의 이름과 동일해야 한다.

- 생성자는 값을 반환하지 않고 반환형도 표시하지 않는다.

 

위의 조건을 만족하면 자바 컴파일러에 의해서 생성자로 인식된다.

 

인스턴스 초기화를 위해 정의한 메소드를 다시한번 보자.

public void initAccount(String acc, String ss, int bal) {
     accNumber = acc;
     ssNumber = ss;
     balance = bal;
}

예제에서 위 메소드가 속한 클래스의 이름은 BankAccount이었다.

따라서 위의 메소드를 생성자가 되게 하려면 다음과 같이 수정하면 된다.

 

public BankAccount(String acc, String ss, int bal) {
     accNumber = acc;
     ssNumber = ss;
     balance = bal;
}

클래스 이름과 동일하고, 반환하지 않으며, 반환형도 선언하지 않았으므로

생성자의 조건을 모두 갖췄다. 이를 활용한 전체적인 예제를 확인해보자.

위 예제에서는 인스턴스의 생성 문장이 다음과 같이 변경되었다.

BankAccount yoon = new BankAccount("12...."

소괄호 안에 값을 전달하고 있다.

위와 같이 문장을 구성하면 '인스턴스 생성 마지막 단계'에서 다음의 생성자가 호출되면서

값들이 전달된다. 그리고 이 값들로 인스턴스 변수가 초기화 된다.

 

public BankAccount(String acc, String ss, int bal) { //생성자

....

}

 

이를 통해 다음과 같은 사실을 알 수 있다.

 

"인스턴스 생성의 마지막 단계는 생성자 호출이다."

"어떠한 이유로든 생성자 호출이 생략된 인스턴스는 인스턴스가 아니다."

 

여기서 의문점이 하나 생길 것이다.

"인스턴스 생성의 마지막 단계는 생성자 호출인데, 앞에 있는 예제는 생성자가 없잖아??"

 

우리는 생성자를 만든 기억은 없지만 생성자는 자동으로 만들어졌다.

자바 컴파일러가 자동으로 만든다.(디폴트 생성자)

 

생성자를 생략한 상태의 클래스를 정의하면 자바 컴파일러가 '디폴트 생성자'라는 것을

클래스의 정의에 넣어준다는 것을 기억하자.