Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

원문 : http://chortle.ccsu.edu/java5/Notes/chap09C/ch09C_1.html

이번장에서는 객체가 무엇인지, 어떻게 사용해야 하는지에 대해서 알아보도록 하겠다. 객체에 대한 모든 토론은 표준 자바 라이브러리(:12)에 포함된 클래스를 기준으로 할 것이다. 자기만의 객체를 만드는 것은 나중에 다루도록 하겠다.

다음과 같은 내용들을 다룰 것이다.
  • Classes
  • 객체(Objects)
  • Reference 변수
  • String 객체
  • 객체의 실행 메서드
  • String 객체의 메서드들
문제 자바는 두종류의 데이터를 가진다. 나열해 보아라.

객체와 원시 데이터

원시 데이터 타입은 비트패턴으로 된 조그마한 데이터이며, 하나의 아이템을 표현하기 위해서 사용한다. 예를 들어 int는 32bit 크기의 비트패턴을 가지며, 정수형 숫자를 표현하기 위해서 사용한다. 자바는 byte, short, int, long, float, double, char, boolean의 8가지의 원시 데이터타입만을 제공한다.
  +-------------+-------------+
  | Primitive   | Objects     | 
  | Data        |             |
  +-------------+-------------+

객체는 많은 처리해야할 데이터와 처리하기 위한 프로세스 정보들을 가진다. 자바는 수천개의 객체 클래스를 제공하며, 프로그래머는 여기에 덧붙여서 쉽게 자신의 클래스를 생성할 수 있다.

여기에서는 왜 객체를 사용해야 하는지에 대한 것들은 다루지 않을 것이다. 이내용들은 26장에서 다룰 것이다.

문제 객체는 원시데이터타입(:12) 을 포함할 수 있는가?

객체의 모양

객체는 데이터와 메서드로 구성된다. 옆의 그림은 객체의 일반적인 모습을 보여주고 있다. 각각의 조그마한 노란색 블럭은 메모리의 바이트를 의미한다. 데이터와 메서드를 불문하고 모두 바이트로 구성된 정보임을 알 수 있다. 이 객체는 Elementary, my dear Waston!이라는 데이터를 포함하며, 이 데이터를 다루기 위한 concat, equals, length, substring 메서드들을 포함한다.

class는 객체의 데이터 타입으로, 객체를 선언하기 위해서 사용한다. 클래스는 집을 짓기 위한 계획과 같은 것으로 생각할 수 있다. 집을 짓기 전에, 여러분은 집을 어떻게 지을것인지에 대한 계획을 세울 것이다. 여기에는 망치, 나무, 못, 시멘트와 같은 재료와 공학적인 지식들이 포함될 것이다. 집을 짓는데 필요한 재료를 데이터, 집을 짓는 방법을 나타내는 공학적인 지식들이 메서드정도가 될 것이다.

옆의 그림의 객체는 자바의 기본객체중 하나인 String 클래스를 보여주고 있다. 이 String 객체는 문자열을 데이터로 가지며, 이문자열을 다루기 위한 여러 메서드들을 포함한다.

문제 String객체에서 length 메서드는 무엇을 하기 위해서 존재한다고 생각되는가 ?

객체의 생성

아래의 프로그램은 String객체를 생성하는 방법을 보여주고 있다.
class StringDemo1
{
  public static void main ( String[] args )
  {
    String str ;

    str = new String( "Elementary, my dear Watson!" );
  }
}

이 프로그램에서 다음 부분을 주목해서 보기바란다.
new String("Elementary, my dear Watson!");
new를 이용해서 새로운 String객체를 생성하고 있음을 알 수 있다. 이 새로운 객체는 String 클래스의 모든 메서드들을 가지게 된다.

이 프로그램은 객체의 메서드들을 이용해서 문자열을 다룰 수 있다. 그렇지만 아직까지는 객체를 생성시킨 것 말고는 하는일이 없다. 이 프로그램을 실행시키면, 아무런 결과도 보여주지 않고 바로 종료해 버릴 것이다.

문제 "You know my methods, Watson"이라는 문자열 데이터를 가지는 새로운 String 객체를 만들어보자.

객체는 실행시간에 생성된다

프로그램이 실행되기전에는 객체는 존재하지 않는다. 프로그램이 시작된 후 새로운 String 객체를 생성할 수 있다.
class StringDemo1
{
  public static void main ( String[] args )
  {
    String str;

    str = new String( "Elementary, my dear Watson!" );

  }
}
String str 선언은 reference 변수를 생성한다. 이것은 단지 선언일 뿐으로 String를 생성하지는 않는다. 변수 str은 새로 생성될 String 객체를 참조하기 위해서 사용된다.

다은 라인에서 new 키워드를 이용해서 새로운 String 객체를 만들었으며, str이 이 객체를 참조하도록 하고 있다.

프로그램의 실행이 중단되면 String객체는 더이상 존재하지 않는다. String 객체가 있던 메모리 공간은 시스템의 다른 프로그램들이 사용할 수 있도록 비워지게 된다.

Object Reference

다음과 같은 코드가 있다고 가정해보자.
str = new String( "Elementary, my dear Watson!" );
이것은 다음과 같이 실행될 것이다.
  • 표현의 평가
new String( "Elementary, my dear Watson!" ); 이것은 새로운 객체를 생성한다. 객체는 메모리상에 위치할 것이므로 객체가 메모리상의 어느 위치에 있는지를 가리키는 무엇인가가 필요할 것이다. reference는 객체를 가리키는 일을 한다. 우리가 레퍼런스를 부르면 자바 가상머신이 객체의 위치를 찾아서 되돌려준다.
  • 변수에 값을 저장
객체를 생성하면 그에 대한 레퍼런스가 생긴다. 이제 이것을 변수에 저장하면 된다. str = The reference to the string just created 이제 str을 이용해서 객체를 사용하면 된다.

때때로 변수 str객체의 이름 혹은 객체명이라고 부르기도 한다. 레퍼런스라고 하는 것보다는 쉽게 알아들을 수 있지만 명확히 레퍼런스와는 다르므로 명확히 알고 사용해야한다. 이에 대한 내용은 나중에 다루기로 하겠다.

문제 객체와 레퍼런스 변수는 어떤점에서 다른가 ?

Before and After

여기에 어떻게 객체와 객체를 가리키는 레퍼런스가 생성되는지를 보여주는 그림이 있다. 왼쪽 그림은 프로그램이 막 실행된 상태로 str 변수는 아무것도 레퍼런스 하고 있지 않다. 이제 new키워드를 이용해서 객체를 생성하고 객체의 레퍼런스를 str에 할당해 보자. str = new String("Elementary, my dear Watson!"); 이제 새로 생성된 객체가 str에 할당되었다. 오른쪽 그림은 str 이 생성된 객체를 레퍼런스 하는 모습을 보여주고 있다.

attachment:creationPicture_1.gif

이렇게 해서 레퍼런스가 할당된 변수는 다른 레퍼런스가 할당되거나 프로그램이 종료되기전까지 유지되게 된다.

문제 객체가 존재하고 있다면, 메서드를 실행시킬 수 있는가 ?

메서드의 실행

아래의 예제 프로그램을 분석해 보도록 하자.
class StringDemo2
{
  public static void main ( String[] args )
  {
    String str;
    int    len;

    str = new String( "Elementary, my dear Watson!" );

    len = str.length();

    System.out.println("The length is: " + len );

  }
}
위의 코드에서 str.length(); 부분이 있는데, str이 레퍼런스하고 있는 객체의 length() 메서드를 호출하겠다는 의미다. 이 메서드는 객체가 가지고 있는 데이터의 문자열의 길이를 넘겨주는 일을 한다. 생성된 객체가 가지고 있는 문자열 데이터는 "Elementary, my dear Watson!" 으로 27을 넘겨줄 것이다. 메서드를 실행시켜서 얻은 결과값은 len에 저장하고 있다.

이렇게 실행된 메서드를 calling a method 라고 한다. 위의 프로그램은 length()메서드를 호출하고 있다.

문제 문자열의 길이를 계산할대, 공백문자와 구둣점 문자도 계산에 포함되는가 ?

Dot Notation (표기)

객체는 다양한 변수와 메서드들을 포함하는데, 이들을 통상적으로 객체의 member이라고 한다. 이러한 멤버들은 dot 표기를 이용해서 접근할 수 있다.
   objectReference . memberName

만약 객체에 있는 어떤 메서드를 실행시키기를 원한다면, 레퍼런스 뒤에 메서드 이름을 적어주면 된다. 이때 호출하는 메서드가 인자를 필요로 한다면 ( )를 통해서 넘겨준다.
   objectReference . memberName (parameter)
인자를 필요로 하지 않는 메서드들도 있는데, 이경우에는 () 만 사용하면 된다.

문제 length() 메서드는 인자를 필요로 하는가 ?

레퍼런스 변수의 선언

레퍼런스 변수를 선언하는 다양한 방법에 대해서 알아보도록 하자.
  • ClassName variableName;
이 선언은 해당 클래스를 위한 레퍼런스 변수를 선언한다. 그러나 아직 객체는 만들어지지 않았다.
  • ClassName variableName = new ClassName( parameter, parameter, ...);
이 선언은 해당 클래스를 위한 레퍼런스 변수를 선언한다. 그리고 new 키워드를 이용해서 객체를 생성한다. 최종적으로 레퍼런스 변수는 새로 생성된 객체의 레퍼런스가 할당된다.
  • ClassName variableNameOne, variagleName Two;
두개의 레퍼런스 변수를 선언할 수도 있다. 이 경우에는 아직 객체가 만들어지지는 않았다.
  • ClassName variableNameOne = new ClassName( parameter, parameter ),
variableNameTwo = new ClassName( parameter, parameter ); 두개의 페퍼런스 변수를 선언하고, new키워드를 이용해서 생성된 객체를 할당한다.

문제 다음 코드에 문제가 있는가 ? String stringG = new String("And yet, it moves!");

String 클래스의 메서드들

String객체는 많은 메서드들을 가지고 있는데, 이들은 또다른 String객체를 생성하기도 한다.

예를 들어 substring(int begin) 메서드는 String 객체에 포함되어 있는 데이터의 일부분을 복사하는 일을 한다. 여기에 substring 메서드를 사용하는 프로그램이 있다.
class StringDemo3
{
  public static void main ( String[] args )
  {
    String str = new String( "Golf is a good walk spoiled." ); // create the original object

    String sub = str.substring(8); //create a new object from the original

    System.out.println( sub );

  }
}

위의 코드에서 str.substring(3)은 str 객체가 가지고 있는 데이터인 Golf is a good walk spoiled 의 8번째 위치부터 마지막까지의 데이터를 복사한다. 이 substring 메서드는 String객체를 생성하는 코드를 포함하고 있으며, 최종적으로는 8번째 위치인 a부터 시작하는 데이터를 가진 새로운 객체를 만들게 된다. 예제에서는 이렇게 해서 만들어진 새로운 객체를 레퍼런스 변수인 sub에 할당하고 있다.

문제 새 객체가 포함하고 있는 문자열은 무엇인가?

새로운 String

아래의 그림은 위의 코드가 실행되는 과정을 보여주고 있다. 이 프로그램은 두개의 레퍼런스 변수를 가지고 실행된다. 그러나 아직은 어떠한 객체로 refer(가리키고)있지 않다. 가장 먼저 다음 코드가 실행이 된다.
   String str = new String( "Golf is a good walk spoiled." );  // 원본 객체의 생성
이제 새로운 String 객체를 생성하고 이것을 변수 str에 할당한다.

attachment:spoiledWalk.gif

이제 아래의 코드가 실행이 된다.
   String str = str.substring(8);  // 원래 객체로 부터 새로운 객체를 생성한다. 
str.substring 메서드는 자신이 가지고 있던 문자열의 8번째 부터 시작하는 새로운 문자열을 가지는 객체를 생성한다. 이렇게 해서 생성된 객체는 변수 sub에 할당이 된다.

String의 다른 메서드들

다음은 String이 가진 많은 메서드들을 보여주고 있다. 이들은 String이 가진 메서드들 중 일부분일 뿐이다.
public char charAt( int index )
public String concat( String str ) 
public boolean endsWith( String suffix ) 

public boolean equals( Object anObject ) 
public boolean equalsIgnoreCase( String anotherString ) 

public int indexOf( int ch ) 
public int indexOf( String str ) 

public int length() 
public boolean startsWith( String prefix ) 

public String substring( int beginIndex ) 
public String substring( int beginIndex, int endIndex ) 
public String toLowerCase() 

public String toUpperCase() 
public String trim() 
다른 메서드들은 앞으로 천천히 다루게 될 것이다.

문제 위의 메서드들 중 객체가 가지고 있는 데이터가 변경되는 메서드를 찾아보라.

Type Wrappers

자바는 primitive 데이터와 objects데이터를 가지고 있음을 알고 있을 것이다. 때때로 일관성을 위해서 primitive 데이터타입을 따로 두지 않고 모두 객체로 두고 싶을 때가 있을 것이다. 이를 위해서 Java 는 Wrapper type 이라는 것을 제공하고 있다. 이 객체들은 내부에 원시데이터 타입을 가지고 있다. 각각의 Wrapper type 은 원시데이터 타입의 첫글자를 대문자로 하는 이름을 가지고 있다.
원시 데이터 타입 Wrapper type
byte Byte
short Short
int Int
long Long
float Float
double Double
char Character
boolean Boolean
예를 들어 원시데이터 타입인 int 형은 32 bit의 크기 가진다. 103 이란 값이 있다면, 이 32bit의 공간에 저장이된다. 이것은 Integer 타입에 동일하게 저장할 수 있다. 물론 Integer 은 객체로, 103이라는 값 외에도 다른 메서드들을 포함하기 때문에 더 많은 메모리 공간을 차지한다.

이들을 이용하는 방법은 나중에 다루도록 하겠다.

문제 String는 wrapper 클래스인가 ?