JAVA 2011. 6. 22. 22:36
객체지향 프로그램은 상호 작용하는 객체들로 이루어지고, 객체 생성에 필요한 클래스를 만드는 일은

프로그래머의 몫이다. 그러므로 프로그래머는 새로운 유형의 객체가 필요하면 클래스를 만들게 되는데

이 때 만들 객체가 기존의 객체와 비슷한 유형을 가지는 클래스를 만들어야 할 경우도 있다. 예를들어 

[이름]
은행 계좌 클래스

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

[기능]
예금한다  
인출한다


전에 만들어 봤던 은행 계좌 메소드를 사용하여 

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

의 객체를 만들어 보았었다. 허나 직불카드번호와 직불카드 사용액을 지불하는 메소드를 추가한다면  

계좌번호 : 111-111-111111
예금주 : 김이박
잔액 : 2100000
직불 카드번호 : 1111222233334444
-------------------------------
예금한다
인출한다
직불카드 사용액을 지불한다. 
 
이렇게 된다면, 저 두 줄때문에 새로운 클래스를 제작하기 보다 이미 존재하는 유사한 클래스를

가져다 필요한 부분을 추가하여 가져올 수 있는 방법을 사용하는 것이 훨씬 바람직한 코딩이다.

위와같이 클래스를 가져다가 확장하여 새로운 클래스를 만드는 기술을 객체지향 프로그래밍에서는 

상속(inheritance) 라 하고 상속받아 만들어진 클래스는 상속받은 클래스의 기능을 모두 사용 할 수

있고 더 확장 할 수도 있다. 

* 클래스 상속의 기초문법

아까 예로 든 것처럼 아래와 같이 만들어야 한다고 치자

계좌번호 : 111-111-111111
예금주 : 김이박
잔액 : 2100000
직불 카드번호 : 1111222233334444
-------------------------------
예금한다 
인출한다
직불카드 사용액을 지불한다. 

일단 기본틀이 되는 은행계좌 클래스는 이렇다.


public
class Account {

String accountNo;

String ownerName;

int balance;

void deposit(int amount){

balance += amount;

}

int withdraw(int amount) throws Exception{

if(balance < amount)

throw new Exception("잔액이 부족 합니다.");

balance -= amount;

return amount;

}

}


이제 이 클래스를 가져다 직불 계좌 클래스를 만들어야 하는데 우선 직불 계좌 클래스의 이름은

"CheckingAccount" , 직불카드 번호는 "cardNo" ,  직불카드 사용액지불 메소드명은 "pay" 라고 

정해 놓고 시작하자.

우선 클래스를 상속하려면 선언이 필요한데 형식은 다음과 같다

class 상속받아새로만들어질클래스명 extends 상속되어질클래스{}
class CheckingAccount extends Account {} 

이다.  앞엣놈이 뒤엣놈을 상속받는다고 생각하면 된다. 자바에서는 이 때 상속을 해주는 

Account 클래스를 슈퍼클래스(superclass) 라 하고 상속 받는 CheckingAccount를

서브클래스(subclass) 라고 한다. 이제 이렇게 클래스를 상속받았으니 추가되는 필드와

메소드를 작성하여 보자.

public class Account {

String accountNo;

String ownerName;

int balance;

void deposit(int amount){

balance += amount;

}

int withdraw(int amount) throws Exception{

if(balance < amount)

throw new Exception("잔액이 부족 합니다.");

balance -= amount;

return amount;

}

}


class CheckingAccount extends Account{

String cardNo;

int pay(String cardNo, int amount) throws Exception{

if(!cardNo.equals(this.cardNo) || (balance < amount))

throw new Exception("지불이 불가능합니다");

return withdraw(amount);

}

}

 
자, 잘보면 위의 Account 클래스를 상속받은 CheckingAccount 클래스가 있다. 

이 클래스는 상속을 받았기 때문에 위에서 상속한 계좌번호, 예금주이름, 잔액 을 따로 또 

선언하지 않고 , 추가된 직불카드 번호 필드만 생성한다. 그리고 직불카드 사용액 지불 메소드만

만든다. 그 메소드인 pay 메소드를 보자, 파라미터로 직불카드번호와 금액을 받는다. 그리고 if문에서

!cardNo.equals(this.cardNo)  이것부터 보면 파라미터로 넘어온 카드번호(cardNo) 와 이미 저장되어

있는 내 카드번호(this.cardNo)가 같지 않다면 (!)  이란 의미이다 즉 내가 카드를 긁었는데 

카드 번호가 맞지 않거나 중간에 || 이것은

피연산자1 || 피연산자2            >   두 값이 모두 false면 false, 그렇지 않으면 true이다.

이 의미이다, 그리고 피연산자2에 해당하는 balance < amount 는 잔액보다 긁으려는 금액이 크다면,

이 의미이다, 즉 앞에 카드번호가 틀리거나 , 잔액보다 큰 금액을 파라미터로 넘겼다면 아래 지불이 

불가능하다고 뜬다. 그리고 둘다 해당되지않는다면 withdraw 메소드에 파라미터로 넘어온 금액을 

넘겨서 잔액 - 파라미터금액을 하고 다시 잔액을 리턴하게 된다. 아까 연산기호 기억이 안난다면
 
 여기 를 다시보면 된다. 참고로 CheckingAccount 클래스를 상속받는 또다른 클래스가 있다면 

그 클래스는 CheckingAccount 와 더불어 Account 까지 상속받아 안에 필드와 메소드를 사용할 수 

있게 된다. 

class Exam {

public static void main(String ar[]){

CheckingAccount obj = new CheckingAccount();

obj.accountNo = "111-111-111111";

obj.ownerName = "송동수";

obj.cardNo = "1111-2222-1111-2222";

obj.deposit(1000000);

try{

int paidAmount = obj.pay("1111-2222-1111-2222", 890000);

System.out.println("지불액 : "+paidAmount);

System.out.println("액 : "+obj.balance);

}catch(Exception e){

}

}

}
 

이런식으로 지불하는 프로그램을 만들어보았다. 우선 계좌번호와, 예금주, 카드번호, 잔액을 넣고

직불카드 지불 메소드에 해당 직불카드 번호와 89만원을 긁으라고 넘겼다. 그럼 위 

CheckingAccount 메소드를 타고 지불액과 잔액이 떨어진다. 

지불액 : 890000

액 : 110000  이렇게 말이다. 만약 잔액보다 많은 금액을 넣는다면 직불이 불가능하다고 뜬다,


*상속과 생성자

앞에선 초기 값을 프로그램을 실행 시키고 대입시켰지만 이같은 방법은 좋은 방법이아니다.

앞에서 배운 생성자를 활용하는 것이 좋은데 알아보자.

class CheckingAccount extends Account{

String cardNo;

CheckingAccount(String accountNo, String ownerName, 

int balance, String cardNo){

this.accountNo = accountNo;

this.ownerName = ownerName;

this.balance = balance;

this.cardNo = cardNo;

}

int pay(String cardNo, int amount) throws Exception{

if(!cardNo.equals(this.cardNo) || (balance < amount))

throw new Exception("지불이 불가능합니다");

return withdraw(amount);

}

}

요렇게 생성자를 만들어 둔다. 이제 이 클래스를 실행하는 프로그램에서 초기에 생성자에

파라미터를 담아 호출하면 시작하자마자 값이 담기고 시작을 하여 효율적이다. 

class Exam {

public static void main(String ar[]){

CheckingAccount obj = new CheckingAccount("111-111-111111",
 "송동수", 0 "1111-2222-1111-2222");

obj.deposit(1000000);

try{

int paidAmount = obj.pay("1111-2222-1111-2222", 890000);

System.out.println("지불액 : "+paidAmount);

System.out.println("액 : "+obj.balance);

}catch(Exception e){

String msg= e.getMessage();

System.out.println(msg);

}

}

}

이렇게 아예 클래스객체를 만들 때 값을 넘겨 초기 값을 담아 두고 그것을 이용하는 편이 좋다.



와오, 점점 복잡해진다.. 






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

'JAVA' 카테고리의 다른 글

JAVA] drawRect 속성 알아보기  (1) 2011.08.18
JAVA] String 원하는 만큼 잘라내기  (0) 2011.08.04
JAVA] 20. 클래스의 정적 구성 요소  (0) 2011.06.17
JAVA] 19. 메소드  (0) 2011.06.15
JAVA] 18. 필드  (0) 2011.06.14
posted by 젊은쎄오
: