객체와 클래스

객체 (Object)

OOP는 먼저 객체를 이해해야 한다. 현실 세계에서 객체의 예를 보자. 당신 앞에 있는 컵, 당신이 지금 사용하고 있는 컴퓨터, 당신 자신이 현실 세계의 객체다. 현실 객체는 다음과 같은 3가지 특징을 가진다.

1. 속성

모든 객체는 속성을 가진다. 당신의 속성은 이름, 핸드폰 번호, 허리 둘레 등이 될 수 있다.

2. 행위

당신은 달린다, 걷는다와 같은 행위를 한다.

3. 유일성

객체는 유일하다. 당신은 유일무이하다.

소프트웨어 객체

소프트웨어 객체 개념은 현실 세계의 객체와 비슷하다. 객체는 데이터와 그 데이터를 조작하는 함수로 구성된 '독립된 단위'다. 현실 세계 객체의 속성은 데이터로, 행위는 함수로 매핑된다.

클래스 (Class)

클래스는 객체의 주조 금형에 해당한다. (금형에 쉿물을 부으면 제품이 만들어 지는데, 제품 하나 하나가 객체라고 생각하면 된다.) 자바에서 객체를 생성하려면 먼저 클래스를 만들어야 한다.

클래스 만드는 법

출석 관리를 위한 소프트웨어를 개발한다고 가정하자. 학생 객체의 속성과 행위를 다음과 같이 추릴 수 있다.

  • 속성: 이름, 총 결석일 수
  • 행위: 결석하다

이제 학생 클래스를 작성할 수 있다.

Student.java
class Student {
	String name;
	int totalAbsenceDays;
	
	void absent() {
		totalAbsenceDays = totalAbsenceDays + 1;
	}

}
class Student {..}
class 키워드 다음에 클래스 이름이 온다. 소스 파일 이름은 클래스 이름과 같게 한다.
String name;
자바 객체는 자신의 상태를 필드에 저장한다. 상태는 OOP의 속성이라는 개념보다 넓은 개념이다.
String name
필드의 데이터 타입 필드 이름
String 클래스는 자바 API에 속한다. String 클래스는 문자열을 표현할 때 사용된다.
int totalAbsenceDays;
int totalAbsenceDays
필드의 데이터 타입 필드 이름
int는 정수를 위한 데이터 타입이다.
void absent() {..}
absent()가 반환하는 값이 없다면 absent() 앞에 void를 붙여야 한다. absent()가 반환하는 값이 있다면 absent() 앞에 반환하는 값의 데이터 타입을 붙여야 한다. 자바에선, absent()를 함수가 아닌 메소드라 부른다.

위 Student 클래스를 단독으로 실행할 수 있도록 만들자. Student.java 파일을 열고, 아래와 같이 메인 메소드를 추가한다.

Student.java
class Student {
	String name;
	int totalAbsenceDays;
	
	void absent() {
		totalAbsenceDays = totalAbsenceDays + 1;
	}
	
	public static void main(String[] args) {
		Student tom = null;
		Student will = null;

		tom = new Student();
		tom.name = "Thomas Edison";

		will = new Student();
		will.name = "William Blake";

		tom.absent();
		will.absent();
		tom.absent();

		System.out.println(tom.totalAbsenceDays);
		System.out.println(will.totalAbsenceDays);
	}
	
}
C:\ Command Prompt
C:\>javac Student.java

C:\>java Studnet
2
1

C:\>

java Student를 명령 프롬프트에서 실행하면 새로운 JVM이 실행되고 Student 클래스의 메인 메소드가 실행된다. JVM이 실행될 때, 클래스 로더는 프로그램을 구성하는 자바 클래스 파일(Student, String, System)을 메모리에 적재한다. 클래스 로더는 자바 API와 관련된 클래스(String, System)의 위치는 이미 알고 있다. Student 클래스의 경우 우리가 클래스로더에게 그 위치를 알려주어야 할 때가 있다. Student 클래스가 없는 디렉터리에서 Student 클래스를 실행하려면 java의 cp 옵션을 사용하여 Student 클래스의 위치를 알려주어야 한다.

public static void main (String[] args) {..}
메인 메소드는 자바 프로그램의 시작점이다. 시작하는 클래스에 메인 메소드를 만들어야 한다.
Student tom = null;
이 문장은 학생 객체를 참조하게 될 레퍼런스 변수를 선언하고 null로 초기화한다. 레퍼런스 변수는 객체를 접근할 때 사용하는 참조 값을 저장한다. 레퍼런스 변수는 객체 그 자체를 저장하지 않는다. 만약 레퍼런스 변수가 어떤 객체도 가리키지 않도록 하려면 null를 할당한다. null도 값이기에, Student tom;과 Student tom = null;은 완전히 다르다.
Student tom; Student tom = null;
tom의 값이 정해지지 않았다. (이를 초기화되지 않았다라고 한다.) null은 레퍼런스 변수의 초기화에 사용된다. null은 변수가 어떤 객체도 참조하지 않음을 나타내는 값이다.
tom = new Student();
이 문장은 Student 타입 변수 tom에 생성한 학생 객체의 참조 값을 할당한다. new Student();는 학생 객체를 힙 메모리 공간에 생성하고, 생성된 학생 객체를 조작하기 위해 필요한 참조 값을 반환한다.
tom.name = "Thomas Edison";
이 문장은 변수 tom을 이용해서 학생 객체의 이름을 셋팅한다. 레퍼런스 변수를 사용해서 객체에 접근하려면 변수명 다음에 .(도트)를 쓰고 객체의 필드나 메소드를 표기한다.
tom.absent();
이 문장은 tom이 참조하는 학생 객체의 absent()를 호출한다.

System.out.println()

자바 기초 예제에서는 결과를 보기 위해서 이 메소드를 자주 사용하게 된다. 다음은 이 메소드의 모든 쓰임새를 보여주고 있다.

StandardOutput.java
class StandardOutput {
    public static void main(String[] args) {
        System.out.println(true);// 불린값을 출력하고 개행
        System.out.println('A');// char 'A'를 출력하고 개행
        char[] x = {'A','B','C'};
        System.out.println(x);//char 타입 배열을 출력하고 개행
        System.out.println(99.9);//double 타입 자료를 출력하고 개행
        System.out.println();//단순히 줄을 바꾼다(개행한다.)
        System.out.println(99.9F);//float 타입 자료를 출력하고 개행
        System.out.println(100);//int 타입 자료를 출력하고 개행
        System.out.println(40000000L);//long 타입 자료를 출력하고 개행
        System.out.println(System.out);//객체의 데이터 타입@해시코드를 출력하고 개행
        System.out.println("표준출력메소드");//문자열을 출력하고 개행
    }
}
C:\ Command Prompt
C:\>javac StandardOutput.java

C:\>java StandardOutput
true
A
ABC
99.9

99.9
100
40000000
java.io.PrintStream@de6ced
표준출력메소드

System.out.println()와 System.out.print()의 유일한 차이는 System.out.println()은 출력 후 라인을 바꾼다는 데 있다.