JAVA 2011. 6. 15. 00:26
오늘은 메소드에 관하여 알아보자, 클래스에 정의된 기능은 자바 클래스의 메소드로 선언해야 한다.

다음을 보자

[이름]
은행 계좌 클래스

[데이터]
계좌번호
예금주 이름
잔액

[기능]
예금한다   ----------  > 메소드로 선언되야 할 부분
인출한다


위 클래스의 기능 부분이 메소드로 선언되어야 할 부분이다.

메소드를 만들 때는 먼저 메소드에 들어갈 로직을 구상하고, 그 로직을 실행하는데 필요한 데이터가

무엇인지와 로직의 실행 결과를 어떤 타입의 데이터로 산출해야 하는지 파악을 해야한다.

메소드의 로직은 메소드 본체안에 써야하고 메소드가 필요로하는 데이터는 파라미터로 표현,

로직의 결과는 return 으로 돌려준다.


public class MethodTest {
String accountNo;
String name;
int balance;

MethodTest(String account, String name, int balance){
this.accountNo = account;
this.name = name;
this.balance = balance;
}
void deposit(int cash){
balance += cash;
}

int withdraw(int cash){
if(balance < cash)
return 0;
balance -= cash;
return cash;
}

}

이런식으로 예금하기와 인출하기의 매소드를 만들어 보았다.

예금하기는 파라미터로 실려온 예금하는 금액을 잔액에 + 시켜버린다.

인출하기는 뽑을 금액이 파라미터로 넘어온 후, 먼저 잔액보다 큰가를 확인한다. 

만약 크다면 0을 리턴하고 작다면 잔액 - 인출액을 한다음 결과값을 리턴한다.

이제 클래스에서 선언되있는 메소드를 호출하는 프로그램을 작성하자.

public class MethodExam {
public static void main(String args[]){
MethodTest obj1 = new MethodTest("111-111-111111", "김이박", 2000000);
MethodTest obj2 = new MethodTest("222-222-111111", "송정임", 12000000);
obj1.deposit(100000);
obj2.withdraw(150000);
printMethod(obj1);
printMethod(obj2);
}

private static void printMethod(MethodTest obj) {
System.out.println("계좌번호 : "+obj.accountNo);
System.out.println("예금주 : "+obj.name);
System.out.println("잔액 : "+obj.balance);
System.out.println();
}

}

위 부분이 obj1 에는 입금을, obj2엔 인출을 수행하고 파라미터에 각각 금액을 적어 넘겼다.

결과는

계좌번호 : 111-111-111111
예금주 : 김이박
잔액 : 2100000

계좌번호 : 222-222-111111
예금주 : 송정임
잔액 : 1185000

이렇게 잘 계산 되어 나온다. 

이렇듯 클래스 외부에서 매소드 호출 방법을 배워보았다. 하지만 클래스 내부에서도 메소드를

호출해야 할 경우가 있는데 보자.


public class Numbers {
int num[];
Numbers(int num[]){
this.num = num;
}
int getTotal(){
int total = 0;
for ( int i = 0; i < num.length; i++){
total += num[i];
}
return total;
}
}

이 메소드에 평균을 구하는 메소드를 추가하려한다. 앞에서는 클래스 객체.매소드명() 이렇게

호출했지만, 지금은 같은 클래스 안이기 때문에 따로 클래스 객체는 필요하지 않고 매소드의

리턴값을 담을 변수하나만 놓으면 된다

total   =  getTotal(); 

이렇게 하면 간단하게 그 메소드를 호출한다. 

public class Numbers {
int num[];
Numbers(int num[]){
this.num = num;
}
int getTotal(){
int total = 0;
for ( int i = 0; i < num.length; i++){
total += num[i];
}
return total;
}
int getAverage(){
int total;
total = getTotal();
int average = total / num.length;
return average;
}
}

이렇게 추가해준다. 그럼 저 메소드 호출부를 만나면 해당 메소드를 가서 메소드 전체를

한번 훑고 다시 돌아와 다음줄을 실행한다. 이걸 실행하는 프로그램을 짜보자.

public class MethodExam2 {
public static void main(String args[]){
int arr[] = {10,20,30,40,50,60,70,80,90,100};
Numbers obj = new Numbers(arr);
int total = obj.getTotal();
int average = obj.getAverage();
System.out.println("합계 : "+total);
System.out.println("평균 : "+average);
}
}

요렇게 짜주면, 일단 Numbers obj = new Numbers(arr); 이 구문으로 위의 배열이

num[] 배열에 쭈르륵 쌓인다. 이 후에  int total = obj.getTotal(); 를 호출하면 

 for ( int i = 0; i < num.length; i++){
total += num[i];
}

이 구문 때문에 num.length 즉, 배열의 갯수니 10부터 100까지 열개니까 num.length는 10을

의미하고 포문은 열 번 돈다는 이야기이다. 그러면서 들어오는 값을 차곡차곡 total변수에

합산한다.  그러고 int average = obj.getAverage(); 를 호출한다. 그럼

 int getAverage(){
int total;
total = getTotal();
int average = total / num.length;
return average;
}
total = getTotal(); 이번에 배운 클래스 안의 매소드 호출로 전부 합산된 550을 가져와 total에

넣는다 그리고 그걸 num.length로 나누니 550 / 10 이 되는 것이고 그 몫을 average에 담고

리턴한다. 그러고 그 리턴값들을 담은 변수를 출력하니

합계 : 550
평균 : 55

라고 찍히게 된다.

하지만 이런 연산을 하는 메소드는 얼마든지 익셉션이 발생할 수 있다 . 당장

int arr[] = new int[0];
Numbers obj = new Numbers(arr);
int total = obj.getTotal();
int average = obj.getAverage(); 

이렇게 배열갯수를 0을 주고 평균을 구하라 한다면, 말이 안되기 때문에 익셉션이 나며 

오류메시지를 뿌린다. 이러한 예외가 있을 수 있으므로 예외처리를 해주어야 한다.

public class MethodExam2 {
public static void main(String args[]){
int arr[] = new int[0];
Numbers obj = new Numbers(arr);
int total = obj.getTotal();
System.out.println("합계 : "+total);
try{
int average = obj.getAverage();
System.out.println("평균 : "+average);
}catch(java.lang.ArithmeticException e){
System.out.println("평균값을 계산하는 도중에 에러발생");
}
}
}
이렇게 예외처리를 했다면 오류없이

합계 : 0
평균값을 계산하는 도중에 에러발생
 
이렇게 뿌려준다. 코드에서는 얼마든지 문제가 일어날 수 있다. 그걸 완벽히 막아내면

좋겠지만 났을 때의 대처방안도 매우 중요하다..

매소드 오버로딩 

자바에서는 메소드 호출문에서 사용한 파라미터의 수, 타입, 순서와 메소드에 선언된

파라미터 변수의 수, 타입, 순서가 맞지 않으면 메소드를 호출할 수 없다. 이걸 이용하면

한 클래스에 같은 이름의 메소드를 파라미터를 다르게 여러개를 선언 할 수 있다는 소리고

이것을 메소드 오버로딩(overloading) 이라고 부른다. 

public class overloading {
String name;
int age;
float height, weight;
overloading(String name, int age, float height, float weight){
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
}
void update(int age){
this.age = age;
}
void update(int age, float height){
this.age = age;
this.height = height;
}
void update(int age, float height,  float weight){
this.age = age;
this.height = height;
this.weight = weight;
}
}
이렇게 update 라는 메소드 이름이 세번이나 중복 되었지만 파라미터가 다르기 때문에

문제없이 코드 작성이 된다.  자바에서는 이렇게 메소드 구분에 사용되는 메소드 이름, 

파라미터 변수의 수, 타입, 순서를 묶어서 메소드 시그니쳐(signature, 서명) 라고 부른다. 

위 update 메소드의 시그니쳐는 update(int),update(int, float), update(int,float,float) 이다.

프로그램을 짜보면

 public class Exam {
public static void main(String args[]){
overloading obj = new overloading("동수", 24, 170.0f, 55.0f);
printMethod(obj);
obj.update(25, 175.0f, 57.0f);
printMethod(obj);
obj.update(26, 180.0f);
printMethod(obj);
obj.update(27);
printMethod(obj);
}

private static void printMethod(overloading obj) {
System.out.println("이름 : "+obj.name);
System.out.println("나이 : "+obj.age);
System.out.println("키 : "+obj.height);
System.out.println("몸무게 : "+obj.weight);
System.out.println();
}
}

이런식으로 각각 같은이름의 메소드를 호출한다.

이름 : 동수
나이 : 24
키 : 170.0
몸무게 : 55.0

이름 : 동수
나이 : 25
키 : 175.0
몸무게 : 57.0

이름 : 동수
나이 : 26
키 : 180.0
몸무게 : 57.0

이름 : 동수
나이 : 27
키 : 180.0
몸무게 : 57.0

그럼 이렇게 쭉쭉 갱신된다. 

매소드를 잘다뤄야 프로그램 그래도 어느정도 안다라고 생각한다 개인적으로..

이렇게 메소드를 이리저리 호출하는 것이 지금에서야 제대로 안게 음.. 부끄러우면서도

다행인거 같다. 100% 활용하도록 연습좀 해야겠다.. 







출판사 : 한빛미디어 , 저자 : 김윤명 님의 뇌를 자극하는 Java프로그래밍에서 공부한 내용입니다.


'JAVA' 카테고리의 다른 글

JAVA] 21. 클래스의 상속  (0) 2011.06.22
JAVA] 20. 클래스의 정적 구성 요소  (0) 2011.06.17
JAVA] 18. 필드  (0) 2011.06.14
자바에서의 인스턴스란?  (1) 2011.06.13
JAVA] 17. 생성자  (0) 2011.06.13
posted by 젊은쎄오
: