7장 클래스 작성
이충기
명지대학교 컴퓨터공학과
들어가며
Q: 축구 게임에서 먼저 공격하는 팀을 정하기 위해 동전을 던진다. 우리는 동전을 던질 때 앞면이 나오느냐 아니면 뒷면이 나오느냐에만 관심이 있다. 또한 동전을 가지고 해야 할 일은 동전을 던지는 것과 동전을 던진 후 결과를 알면 된다. 이 동전을 효과적으로 나타낼 수 있는 방법을 기술하라.
A:
클래스와 객체
자바 프로그램 = 클래스들의 모음
클래스: 객체를 정의하기 위한 설계도
객체는 사람과 자동차와 같은 실 세계의 객체나 은행 계좌 나 모양과 같은 추상 개념을 나타낸다.
객체 = 속성(데이터) + 행동(연산)
객체의 속성은 클래스에서 변수로 행동은 메소드로 나타 낸다.
한 클래스로부터 여러 개의 객체들을 생성할 수 있다. 이 객체들을 서로 구별하기 위해 참조변수를 사용한다.
예: Person 클래스
사람을 모델
- 속성: 이름, 나이
- 행동: 이름을 알려 준다, 나이를 알려 준다, 이름을 변경한다, 나이를 변경한다
Person 클래스의 객체는 특정한 사람을 나타낸다.
예: Person 클래스와 객체
사람
Person 클래스
이름: 홍길동 나이: 25
Person 객체
이름: 손오공 나이: 17
한 클래스로부터 여러 객체들 생성
클래스
클래스는 데이터를 나타내는 변수 선언문(들)과 연산(들)을 나타내는 메소드 정의(들)을 포함한다.
int x, y;
char ch; 변수 선언문
메소드 정의
클래스 구조
클래스는 머리부와 몸체로 이루어진다. public class 클래스이름
{
변수(혹은 상수) 선언문들 메소드 정의들
}
변수와 메소드는 각각 모델하는 객체의 데이터와 연산을 나타낸다.
변수는 객체 변수와 클래스 변수로 나누어진다.
메소드는 객체 메소드와 클래스 메소드로 나누어진다.
객체 메소드 분류
객체 메소드는 객체에 적용되는 메소드이다.
객체 메소드는 수행하는 역할에 따라 접근자 메소드와 변경자 메소드로 나눈다.
접근자 메소드는 객체 변수의 값이나 어떤 값을 계산하여 반환하는 메소드이다.
변경자 메소드는 객체 변수의 값을 바꾸는 메소드이다.
접근자와 변경자 메소드
접근자메소드:
“get” 메소드 . . .
( 메소드명은 보통 “get”으로 시작)
객체의 데이터에 대한 값을 반환한다
객체 변수 값을 반환할 수 있다 계산되는 어떤 값을 반환할 수 있다
변경자 메소드:
“set” 메소드 . . .
( 메소드명은 보통 “set”으로 시작)
객체 변수 값을 바꾸는 메소드
객체 변수들에 대한 접근을 제한하 고 그에 따라 변수 값을 제어하도록 한다
예: Person 클래스
public class Person {
public String name; // 이름
public int age; // 나이
// 변경자 메소드: 이름을 주어진 값으로 변경한다
public void setName(String NewName) { name = NewName; } // 변경자 메소드: 나이를 주어진 값으로 변경한다
public void setAge(int NewAge) { age = NewAge; } // 접근자 메소드: 이름을 반환한다
public String getName( ) { return name; } // 접근자 메소드: 나이를 반환한다
public int getAge( ) { return age; }
클래스와 객체의 이용
1. 클래스의 한 실례인 객체를 참조하는 변수를 선언한다.
2. new라는 연산자를 이용하여 클래스의 한 객체를 만들고 이를 1에서 선언한 참조변수가 가리키게 한다.
3. 만든 객체를 이용하여 원하는 일을 수행하기 위해서 객체의 적절한 메소드를 호출한다.
객체 메소드 호출 방법
<객체를 가리키는 참조변수명>.<객체 메소드명>(실제 매개변수 목록)
객체 메소드가 매개변수를 가지고 있지 않다면 실제 매개변수 목록은 비게 된다.
다음 코드는 Person 객체를 생성한 후 참조 변수 p가 가리키게
하고 그 Person 객체의 이름을 ‘홍길동’으로 변경하기 위해 Person 클래스 내에 정의된 setName 메소드를 호출한다.
Person p = new Person( );
p.setName(“홍길동”);
접근 수정자
접근 수정자는 클래스, 변수나 메소드의 접근 범위를 나타낸다.
접근 수정자: public, private, package, protected
public으로 선언된 클래스의 변수들과 메소드들은 프로그램 내의 어떤 다른 클래스 내에서 이용할 수 있다.
private로 선언된 클래스의 변수들과 메소드들은 그 클래스 내에서 만 이용할 수 있다.
package 접근 수정자는 기본 접근 수정자로서 해당 클래스, 메소드 나 변수가 같은 패키지 내의 모든 클래스에서 접근 가능하다는 것 을 의미한다.
protected 수정자는 10장에서 다루어진다.
정보 감추기
메소드 사용자는 메소드를 이용하기 위해 메소드 구현 에 대해 알 필요가 없다.
클래스 내의 공개하기가 부적절한 데이터를 저장하는 객체 변수는 접근을 제한할 필요가 있다.
정보 감추기는 접근 수정자에 의해 제공된다.
캡슐화
캡슐화는 클래스 정의의 상세한 내용을 감추는 과정이다.
클래스를 다른 프로그래머가 그 클래스의 감춰진 상세 내역 들을 알지 못해도 사용할 수 있도록 정의하는 것이다.
클래스 정의를 크게 인터페이스(API)와 구현으로 나눌 수 있다.
클래스 인터페이스
프로그래머에게 한 클래스를 사용하기 위해 알 필요가 있 는 모든 것을 알려준다.
클래스 인터페이스는 다음을 포함한다.
- public 메소드(들)의 머리부 - public으로 선언된 상수들
- public 메소드와 public 상수들의 사용법을 알려주는 주석문
클래스 구현
클래스 구현은 다른 프로그래머가 볼 수 없도록 감추어 진다.
한 클래스의 구현은 다음을 포함한다.
- 모든 private 변수들과 private 메소드들 - 모든 메소드의 정의(메소드 몸체 포함)
UML 클래스 그림
클래스의 주요 구성 요소들을 직사각형으로 표현한다.
직사각형의 내부는 세 부분으로 나누어진다.
1. 윗 부분: 클래스 이름
2. 중간 부분: 각 변수를 다음과 같이 표현한다.
+(-) 변수 이름: 데이터 형
3. 아래 부분: 각 메소드를 다음과 같이 표현한다.
+(-) 메소드명(형식매개변수 목록): 반환유형
예: UML 클래스 그림
Person + name: String
+ age: int
+ setName(String newName): void + setAge(int newAge): void
+ getName(): String
+ getAge(): int
예제 프로그램 작성
문제: 한 은행의 계좌 관리 프로그램에서 은행계좌를 나타내라.
은행계좌를 어떻게 모델할까?
- 은행계좌를 대표하는 속성은 무엇일까?
- 은행계좌에 적용 가능한 연산들은 무엇일까?
클래스 설계: 은행계좌
대표 속성
- 예금주 이름 - 잔고
연산
- 예금주 이름을 주어진 값으로 변경한다 - 잔고를 주어진 값으로 변경한다
- 예금주 이름을 알려 준다 - 잔고를 알려 준다
- 주어진 금액을 입금한다 - 주어진 금액을 출금한다
- 예금 계좌의 모든 데이터 값을 알려 준다
구현: 은행계좌 클래스
클래스의 이름: Account
클래스의 구조
public class Account {
// 변수 선언문(들) . . .
// 메소드 정의(들) . . .
}
예금계좌 클래스
public class Account { String ownerName;
int balance;
public void setOwnerName(String name) { ownerName = name;
}public void setBalance(int amount) { balance = amount;
public void deposit(int amount) {} balance = balance + amount;
public void withdraw(int amount) {} balance = balance - amount;
}
객체 변수
변경자 메소드
계속
예금계좌 클래스 (계속)
public String getOwnerName( ) { return ownerName;
}
public int getBalance( ) { return balance;
}
public String toString( ) { String result = "";
result = result + "예금주 이름:" + getOwnerName( ) + "\n";
result = result + "잔고: " + getBalance( );
return result;
}
접근자
메소드
객체 사용하기
클래스의 한 보기인 객체를 만들어야 한다.
이는 다음과 같은 세 과정을 포함한다.
1. 객체를 가리키는 참조 변수를 정의한다.
Account acct;
2. 클래스의 객체를 만든다.
acct = new Account( );
위의 두 과정은 하나로 합칠 수 있다.
Account acct = new Account( );
예제: Account 객체 사용하기
문제: 한 예금계좌를 개설하여 입금과 출금을 하고 난 후 계좌의 내역을 출력한다.
main 메소드 설계
- 변수: 예금계좌 객체 참조변수 - 알고리즘
1. 새 예금계좌를 만든다.
2. 계좌의 예금주는 ‘홍길동’으로 한다.
3. 계좌의 초기 입금액은 10,000원이다.
4. 계좌에 3,000원을 입금한다.
5. 계좌에서 5,000원을 출금한다.
Account 객체 사용하기
public class Driver {
public static void main (String[ ] args) { Account acct;
// 새 예금계좌를 만든다
Account acct = new Account( );
// 계좌의 예금주를 ‘홍길동’으로 한다 acct.setOwnerName("홍길동");
// 계좌의 초기 입금액은 10,000원이다 acct.setBalance(10000);
// 3,000원을 입금한다 acct.deposit(3000);
// 5,000원을 출금한다 acct.withdraw(5000);
// 계좌의 내역을 출력한다
System.out.println(acct.toString( ));
} }
두 번째 클래스가 Account 클래스의
한 보기인 객체를 만들기 위해 사용된다.
Driver 클래스는
main 메소드를 가지고
있고 한 프로그램으로서 실행된다.
Account 객체 사용하기
public class Driver {
public static void main (String[ ] args) { Account acct;
// 새 예금계좌를 만든다 Account acct = new Account( );
// 계좌의 예금주를 ‘홍길동’으로 한다 acct.setOwnerName("홍길동");
// 계좌의 초기 입금액은 10,000원이다 acct.setBalance(10000);
// 3,000원을 입금한다 acct.deposit(3000);
// 5,000원을 출금한다 acct.withdraw(5000);
// 계좌의 내역을 출력한다
먼저, acct 라는 변수를 선언한다.
이 시점에서, acct는 아무 것도 가리키지
않는다.
다음으로, acct가
가리키는 한 객체를 만든다.
프로그램 실행 방법
한 프로그램 내에 여러 개의 클래스들이 있고 각 클래스가 별도의 파일에 저장되어 있는 경우 우리는 그 파일들을 같은 폴더에 저장한다.
이 경우 전체 프로그램을 실행하기 위한 과정은 다음과 같다.
1. 각 클래스를 컴파일한다.
2. main 메소드를 포함하고 있는 클래스를 실행한다.
예제 프로그램 실행 방법
예제 프로그램을 구성하는 Account.java와 Driver.java는 같은 폴더에 별도의 파일로 저장되어 있다고 가정한다.
예제 프로그램을 명령 프롬프트에서 실행하는 과정
1. javac Account.java 2. javac Driver.java 3. java Driver
요약
클래스와 객체
클래스 구조
클래스와 객체의 이용
정보 감추기와 캡슐화
UML 클래스 그림
예제 프로그램 작성
프로그램 실행 방법