상속과 인터페이스 클래스의 상속에 대하여 인터페이스에 대하여
상속과 인터페이스 01. 클래스의 상속 언제 상속이 필요한가? • 기존 클래스와 유사한 클래스를 만들어야 할 경우
상속과 인터페이스 01. 클래스의 상속 상속이란? • 상속(inheritance) : 기존 클래스를 확장해서 새로운 클래스를 만드는 기술
01. 클래스의 상속 상속과 인터페이스 클래스 상속의 기초 문법 [예제 6-1] 은행 계좌 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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;
01. 클래스의 상속 상속과 인터페이스 클래스 상속의 기초 문법 • 다른 클래스를 상속하는 클래스의 선언 - 제일 먼저 해야할 일은 정의된 클래스와 추가되는 필드, 메소드 이름을 정하는 것
01. 클래스의 상속 상속과 인터페이스 클래스 상속의 기초 문법 • 다른 클래스를 상속하는 클래스의 선언 - extends 키워드를 이용하여 상속할 클래스 이름을 명시해야 함
01. 클래스의 상속 상속과 인터페이스 클래스 상속의 기초 문법 [예제 6-2] 은행 계좌 클래스를 상속하는 직불 계좌 클래스 extends 절 1 2 3 4 5 6 7 8 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); } 직불카드 번호에 해당하는 필드 직불카드 사용액을 지불한다에 해당하는 메소드
01. 클래스의 상속 상속과 인터페이스 클래스 상속의 기초 문법 [예제 6-3] 직불 계좌 클래스를 사용하는 프로그램 1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class InheritanceExample1 { public static void main(String args[]) { CheckingAccount obj = new CheckingAccount(); obj.accountNo = "111-22-33333333"; obj.ownerName = "홍길동"; obj.cardNo = "5555-6666-7777-8888"; obj.deposit(100000); try { int paidAmount = obj.pay("5555-6666-7777-8888", 47000); System.out.println("지불액:" + paidAmount); System.out.println("잔액:" + obj.balance); } catch (Exception e) { String msg = e.getMessage(); System.out.println(msg); Account 클래스로부터 상속받은 필드 사용 Account 클래스로부터 상속받은 메소드 호출
01. 클래스의 상속 상속과 인터페이스 상속과 생성자 [예제 6-4] 생성자가 추가된 직불 계좌 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 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); 슈퍼클래스로부터 상속받은 필드들을 초기화합니다. 클래스 안에 선언된 필드를 초기화합니다.
01. 클래스의 상속 상속과 인터페이스 상속과 생성자 [예제 6-5] 직불 계좌 클래스의 생성자를 사용하는 프로그램 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class InheritanceExample2 { public static void main(String args[]) { CheckingAccount obj = new CheckingAccount("111-22-33333333", "홍길동", 0, "5555-6666-7777-8888"); obj.deposit(100000); try { int paidAmount = obj.pay("5555-6666-7777-8888", 47000); System.out.println("지불액:" + paidAmount); System.out.println("잔액:" + obj.balance); } catch (Exception e) { String msg = e.getMessage(); System.out.println(msg); CheckingAccount 클래스의 생성자 호출 [예제 6-1] [예제 6-4] [예제 6-5]
01. 클래스의 상속 상속과 인터페이스 생성자가 있는 클래스의 상속 [예제 6-6] 생성자가 있는 Account 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Account { String accountNo; String ownerName; int balance; Account(String accountNo, String ownerName, int balance) { this.accountNo = accountNo; this.ownerName = ownerName; this.balance = balance; } void deposit(int amount) { balance += amount; int withdraw(int amount) throws Exception { if (balance < amount) throw new Exception("잔액이 부족합니다."); balance -= amount; return amount; [예제 6-6] [예제 6-4]
01. 클래스의 상속 상속과 인터페이스 생성자가 있는 클래스의 상속 • [예제 6-6], [예제 6-4]를 컴파일할 때 에러가 발생한 이유 자바 컴파일러는 생성자 안의 첫번째 명령문이 슈퍼클래스의 생성자 호출문이 아니면 자동으로 슈퍼클래스의 파라미터 없는 생성자(no-arg constructor) 호출문을 추가하기 때문 • 슈퍼클래스의 생성자 호출문 작성 방법
01. 클래스의 상속 상속과 인터페이스 생성자가 있는 클래스의 상속 [예제 6-7] 슈퍼클래스의 생성자를 호출하는 직불 계좌 클래스 1 2 3 4 5 6 7 8 9 10 11 12 class CheckingAccount extends Account { String cardNo; CheckingAccount(String accountNo, String ownerName, int balance, String cardNo) { super(accountNo, ownerName, 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); 슈퍼클래스의 생성자 호출 [예제 6-6] [예제 6-7]
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩 • 메소드 오버라이딩이 필요한 경우 • 메소드 오버라이딩(method overriding)의 방법 - 슈퍼클래스와 똑같은 시그니쳐를 갖는 메소드를 서브클래스에 선언
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩 [예제 6-8] 슈퍼클래스의 메소드를 오버라이드하는 마이너스 통장 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 class CreditLineAccount extends Account { int creditLine; CreditLineAccount(String accountNo, String ownerName, int balance, int creditLine) { super(accountNo, ownerName, balance); this.creditLine = creditLine; } int withdraw(int amount) throws Exception { if ((balance + creditLine) < amount) throw new Exception("인출이 불가능합니다."); balance -= amount; return amount; 마이너스 한도 필드 인출한다 기능을 다시 구현하는 메소드
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩 [예제 6-9] 마이너스 통장 클래스를 사용하는 프로그램 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class InheritanceExample3 { public static void main(String args[]) { CreditLineAccount obj = new CreditLineAccount( "000-11-111111", "김선달", 10000, 20000000); try { int amount = obj.withdraw(50000); System.out.println("인출액:" + amount); System.out.println("잔액:" + obj.balance); System.out.println("마이너스 한도:" + obj.creditLine); } catch (Exception e) { System.out.println(e.getMessage()); [예제 6-6] [예제 6-8]
상속과 인터페이스 01. 클래스의 상속 메소드 오버라이딩 • 메소드 오버라이딩이 필요한 또다른 경우의 예
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩 [예제 6-10] 슈퍼클래스의 메소드를 오버라이드하는 포인트 적립 계좌 클래스 1 2 3 4 5 6 7 8 9 10 11 class BonusPointAccount extends Account { int bonusPoint; // 누적 포인트 BonusPointAccount(String accountNo, String ownerName, int balance, int bonusPoint) { super(accountNo, ownerName, balance); this.bonusPoint = bonusPoint; } void deposit(int amount) { // 예금한다 balance += amount; bonusPoint += (int) (amount * 0.001);
상속과 인터페이스 01. 클래스의 상속 메소드 오버라이딩 • 슈퍼클래스에 있는 오버라이드된 메소드를 호출하는 방법
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩 [예제 6-11] 오버라이드된 메소드를 호출하는 포인트 적립 계좌 클래스 1 2 3 4 5 6 7 8 9 10 11 class BonusPointAccount extends Account { int bonusPoint; // 누적 포인트 BonusPointAccount(String accountNo, String ownerName, int balance, int bonusPoint) { super(accountNo, ownerName, balance); this.bonusPoint = bonusPoint; } void deposit(int amount) { // 예금한다 super.deposit(amount); bonusPoint += (int) (amount * 0.001); 슈퍼클래스의 deposit 메소드 호출
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩 [예제 6-12] 포인트 적립 계좌 클래스를 사용하는 프로그램 1 2 3 4 5 6 7 8 class InheritanceExample4 { public static void main(String args[]) { BonusPointAccount obj = new BonusPointAccount( "333-33-333333", "김미영", 0, 0); obj.deposit(1000000); System.out.println("잔액:" + obj.balance); System.out.println("누적 포인트:" + obj.bonusPoint); } [예제 6-6] [예제 6-11]
01. 클래스의 상속 상속과 인터페이스 상속을 금지하는 final 키워드 [예제 6-13] final 키워드를 추가한 Account 클래스 final 키워드 추가 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 final class Account { String accountNo; String ownerName; int balance; Account(String accountNo, String ownerName, int balance) { this.accountNo = accountNo; this.ownerName = ownerName; this.balance = balance; } void deposit(int amount) { balance += amount; int withdraw(int amount) throws Exception { if (balance < amount) throw new Exception("잔액이 부족합니다."); balance -= amount; return amount; [예제 6-11]
01. 클래스의 상속 상속과 인터페이스 메소드 오버라이딩을 금지하는 final 키워드 [예제 6-14] withdraw 메소드에 final 키워드를 추가한 Account 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Account { String accountNo; String ownerName; int balance; Account(String accountNo, String ownerName, int balance) { this.accountNo = accountNo; this.ownerName = ownerName; this.balance = balance; } void deposit(int amount) { balance += amount; final int withdraw(int amount) throws Exception { if (balance < amount) throw new Exception("잔액이 부족합니다."); balance -= amount; return amount; final 키워드 추가
01. 클래스의 상속 상속과 인터페이스 인스턴스화를 금지하는 abstract 키워드 [예제 6-15] abstract 키워드를 추가한 Account 클래스 abstract 키워드 추가 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 abstract class Account { String accountNo; String ownerName; int balance; Account(String accountNo, String ownerName, int balance) { this.accountNo = accountNo; this.ownerName = ownerName; this.balance = balance; } void deposit(int amount) { balance += amount; int withdraw(int amount) throws Exception { if (balance < amount) throw new Exception("잔액이 부족합니다."); balance -= amount; return amount; abstract 키워드가 붙은 클래스를 추상 클래스(abstract class)라고 함
01. 클래스의 상속 상속과 인터페이스 인스턴스화를 금지하는 abstract 키워드 [예제 6-16] 추상 클래스를 인스턴스화하는 잘못된 프로그램 1 2 3 4 5 class InheritanceExample5 { public static void main(String args[]) { Account obj = new Account("111-222-333333", "임꺽정", 0); } [예제 6-15]
상속과 인터페이스 01. 클래스의 상속 추상 메소드 • 추상 메소드(abstract method) : 메소드 본체가 없는 메소드 • 추상 메소드가 필요한 경우 [데이터] 제목 발송자 이름 [이름] 메시지 발송 클래스 [기능] 메시지를 송신한다 상 속 [데이터] 제목 발송자 이름 발송자 이메일 주소 이메일 내용 [이름] 이메일 송신 클래스 [기능] 메시지를 송신한다 회신 전화번호 메시지 본문 [이름] 문자메시지 송신 클래스
상속과 인터페이스 01. 클래스의 상속 추상 메소드 • 추상 메소드의 선언 방법
01. 클래스의 상속 상속과 인터페이스 추상 메소드 [예제 6-17] 추상 클래스를 포함하는 클래스 – 메시지 발송 클래스 클래스 자체도 추상 클래스로 선언 1 2 3 4 5 6 7 8 9 abstract class MessageSender { String title; String senderName; MessageSender(String title, String senderName) { this.title = title; this.senderName = senderName; } abstract void sendMessage(String recipient); 추상 메소드 선언
01. 클래스의 상속 상속과 인터페이스 추상 메소드 [예제 6-18] 메시지 발송 클래스를 상속하는 이메일 송신 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class EMailSender extends MessageSender { String senderAddr; String emailBody; EMailSender(String title, String senderName, String senderAddr, String emailBody) { super(title, senderName); this.senderAddr = senderAddr; this.emailBody = emailBody; } void sendMessage(String recipient) { System.out.println("------------------------------"); System.out.println("제목: " + title); System.out.println("보내는 사람: " + senderName + " " + senderAddr); System.out.println("받는 사람: " + recipient); System.out.println("내용: " + emailBody); 슈퍼클래스의 메소드를 오버라이드하는 메소드
01. 클래스의 상속 상속과 인터페이스 추상 메소드 [예제 6-19] 메시지 발송 클래스를 상속하는 문자 메시지 송신 클래스 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class SMSSender extends MessageSender { String returnPhoneNo; String message; SMSSender(String title, String senderName, String returnPhoneNo, String message) { super(title, senderName); this.returnPhoneNo = returnPhoneNo; this.message = message; } void sendMessage(String recipient) { System.out.println("------------------------------"); System.out.println("제목: " + title); System.out.println("보내는 사람: " + senderName); System.out.println("전화번호: " + recipient); System.out.println("회신 전화번호: " + returnPhoneNo); System.out.println("메시지 내용: " + message); 슈퍼클래스의 메소드를 오버라이드하는 메소드
상속과 인터페이스 01. 클래스의 상속 추상 메소드 [예제 6-20] 이메일 송신 클래스와 문자 메시지 송신 클래스를 사용하는 프로그램 1 2 3 4 5 6 7 8 9 class InheritanceExample6 { public static void main(String args[]) { EMailSender obj1 = new EMailSender("생일을 축하합니다", "고객센터", "admin@dukeeshop.co.kr", "10% 할인쿠폰이 발행되었습니다."); SMSSender obj2 = new SMSSender("생일을 축하합니다", "고객센터", "02-000-0000", "10% 할인쿠폰이 발행되었습니다."); obj1.sendMessage("hatman@yeyeye.com"); obj1.sendMessage("stickman@hahaha.com"); obj2.sendMessage("010-000-0000"); } 추상 메소드를 구현하는 메소드를 호출합니다.
01. 클래스의 상속 상속과 인터페이스 추상 메소드 [예제 6-21] 메시지 발송 클래스를 상속하는 클래스 – 잘못된 예 1 3 4 5 class SillySender extends MessageSender { SillySender(String title, String senderName) { // 생성자 super(title, senderName); }
상속과 인터페이스 01. 클래스의 상속 클래스 변수의 다형성 • 클래스 변수의 다형성
상속과 인터페이스 01. 클래스의 상속 클래스 변수의 다형성 • 클래스 변수의 다형성의 예
01. 클래스의 상속 상속과 인터페이스 클래스 변수의 다형성 [예제 6-22] 클래스 변수의 다형성을 활용하는 프로그램 (1) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class InheritanceExample7 { public static void main(String args[]) { Account obj1 = new Account("111-22-333333", "임꺽정", 10000); CheckingAccount obj2 = new CheckingAccount("444-55-666666", "홍길동", 20000, "5555-6666-7777-8888"); CreditLineAccount obj3 = new CreditLineAccount("777-88-999999", "김선달", 30000, 20000000); BonusPointAccount obj4 = new BonusPointAccount("000-00-000000", "김미영", 0, 0); printAccountInfo(obj1); printAccountInfo(obj2); printAccountInfo(obj3); printAccountInfo(obj4); } static void printAccountInfo(Account obj) { System.out.println("계좌번호:" + obj.accountNo); System.out.println("예금주 이름:" + obj.ownerName); System.out.println("잔액:" + obj.balance); System.out.println(); 다양한 타입의 객체를 가지고 메소드를 호출합니다. 다양한 타입의 객체를 한 타입의 파라미터 변수로 받습니다.
01. 클래스의 상속 상속과 인터페이스 다형성과 메소드 오버라이딩 [예제 6-23] 클래스 변수의 다형성을 활용하는 프로그램 (2) 1 2 3 4 5 6 7 8 9 10 11 12 class InheritanceExample8 { public static void main(String args[]) { EMailSender obj1 = new EMailSender("생일을 축하합니다", "고객센터", "admin@dukeeshop.co.kr", "10% 할인쿠폰이 발행되었습니다."); SMSSender obj2 = new SMSSender("생일을 축하합니다", "고객센터", "02-000-0000", "10% 할인쿠폰이 발행되었습니다."); send(obj1, "hatman@yeyeye.com"); send(obj1, "stickman@hahaha.com"); send(obj2, "010-000-0000"); } static void send(MessageSender obj, String recipient) { obj.sendMessage(recipient); 서브클래스 객체 obj1, obj2를 가지고 메소드를 호출합니다. 슈퍼클래스 타입의 파라미터 변수 어느 클래스의 sendMessage 메소드가 호출될까요?
상속과 인터페이스 02. 인터페이스 인터페이스란? • 자바에서는 클래스의 다중 상속을 허용하지 않음
상속과 인터페이스 02. 인터페이스 인터페이스의 선언 • 인터페이스의 선언 방법
02. 인터페이스 상속과 인터페이스 인터페이스의 선언 [예제 6-24] 대출가능 인터페이스 인터페이스의 선언을 시작하는 키워드 interface Lendable { void checkOut(String borrower, String date); void checkIn(); } 1 2 3 4 이렇게 선언해도 마찬가지입니다. interface Lendable { abstract void checkOut(String borrower, String date); abstract void checkIn(); } 1 2 3 4 대출한다 메소드 반납한다 메소드
상속과 인터페이스 02. 인터페이스 인터페이스를 구현하는 클래스의 선언 • 인터페이스를 구현하는 클래스의 선언 방법
02. 인터페이스 상속과 인터페이스 인터페이스를 구현하는 클래스의 선언 [예제 6-25] 대출가능 인터페이스를 구현하는 단행본 클래스 implements 절 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class SeparateVolume implements Lendable { String requestNo; // 청구번호 String bookTitle; // 제목 String writer; // 저자 String borrower; // 대출인 String checkOutDate; // 대출일 byte state; // 대출상태 SeparateVolume(String requestNo, String bookTitle, String writer) { this.requestNo = requestNo; this.bookTitle = bookTitle; this.writer = writer; } public void checkOut(String borrower, String date) { // 대출한다 if (state != 0) return; this.borrower = borrower; this.checkOutDate = date; this.state = 1; System.out.println("*" + bookTitle + " 이(가) 대출되었습니다."); System.out.println("대출인:" + borrower); System.out.println("대출일:" + date + "\n"); public void checkIn() { // 반납한다 this.borrower = null; this.checkOutDate = null; this.state = 0; System.out.println("*" + bookTitle + " 이(가) 반납되었습니다.\n"); 인터페이스의 메소드를 구현할 때 반드시 써야 하는 키워드 인터페이스의 메소드를 구현할 때 반드시 써야 하는 키워드
02. 인터페이스 상속과 인터페이스 인터페이스를 구현하는 클래스의 선언 • extends 절과 implements 절이 모두 있는 클래스의 선언 방법
02. 인터페이스 상속과 인터페이스 인터페이스를 구현하는 클래스의 선언 [예제 6-26] 대출가능 인터페이스를 구현하는 부록 CD 클래스 1 2 3 4 5 6 7 8 class CDInfo { String registerNo; // 관련번호 String title; // 타이틀 CDInfo(String registerNo, String title) { this.registerNo = registerNo; this.title = title; } 상속 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class AppCDInfo extends CDInfo implements Lendable { String borrower; // 대출인 String checkOutDate; // 대출일 byte state; // 대출상태 AppCDInfo(String registerNo, String title) { super(registerNo, title); } public void checkOut(String borrower, String date) { if (state != 0) return; this.borrower = borrower; this.checkOutDate = date; this.state = 1; System.out.println("*" + title + " CD가 대출되었습니다."); System.out.println("대출인:" + borrower); System.out.println("대출일:" + date + "\n"); public void checkIn() { this.borrower = null; this.checkOutDate = null; this.state = 0; System.out.println("*" + title + " CD가 반납되었습니다.\n"); implements 절
02. 인터페이스 상속과 인터페이스 인터페이스를 구현하는 클래스의 선언 [예제 6-27] 단행본 클래스와 부록 CD 클래스를 사용하는 프로그램 1 2 3 4 5 6 7 8 9 10 class InterfaceExample1 { public static void main(String args[]) { SeparateVolume obj1 = new SeparateVolume("863ㅂ774개", "개미", "베르베르"); AppCDInfo obj2 = new AppCDInfo("2005-7001", "Redhat Fedora"); obj1.checkOut("김영숙", "20060315"); obj2.checkOut("박희경", "20060317"); obj1.checkIn(); obj2.checkIn(); } [예제 6-25] ~ [예제 6-27] 인터페이스의 컴파일 방법
02. 인터페이스 상속과 인터페이스 인터페이스의 사용 방법 • 인터페이스를 가지고 할 수 없는 일 - 객체 생성에 사용하는 것은 불가능 클래스에 메소드 로직을 상속해줄 수 없음 • 인터페이스를 가지고 할 수 있는 일 클래스의 선언 방법을 제한할 수 있음 인터페이스 변수 선언에 사용됨
02. 인터페이스 상속과 인터페이스 클래스의 선언 방법을 제한하는 인터페이스 [예제 6-28] Lendable 인터페이스를 구현하는 클래스의 예 – 잘못된 예 1 2 3 4 5 6 class Dictionary implements Lendable { String title; Dictionary(String title) { this.title = title; }
02. 인터페이스 상속과 인터페이스 인터페이스 변수의 다형성 • 인터페이스 변수의 선언 • 인터페이스 변수의 사용 - 인터페이스 변수에는 그 인터페이스를 구현하는 클래스의 객체를 대입할 수 있음
02. 인터페이스 상속과 인터페이스 인터페이스 변수의 다형성 [예제 6-29] Lendable 인터페이스 변수의 다형성을 이용하는 프로그램 1 2 3 4 5 6 7 8 9 10 11 12 13 class InterfaceExample2 { public static void main(String args[]) { Lendable arr[] = new Lendable[3]; arr[0] = new SeparateVolume("883ㅇ", "푸코의 진자", "에코"); arr[1] = new SeparateVolume("609.2”, "서양미술사", "곰브리치"); arr[2] = new AppCDInfo("02-17", "XML을 위한 자바 프로그래밍"); checkOutAll(arr, "윤지혜", "20060315"); } static void checkOutAll(Lendable arr[], String borrower, String date) { for (int cnt = 0; cnt < arr.length; cnt++) arr[cnt].checkOut(borrower, date); 인터페이스 타입의 배열 배열에 여러 타입의 객체 저장 배열을 파라미터로 넘겨줍니다 배열의 모든 항목에 대해 checkOut 메소드 호출
02. 인터페이스 상속과 인터페이스 인터페이스의 상수 필드 • 인터페이스의 상수 필드 선언 방법 (1) • 인터페이스의 상수 필드 선언 방법 (2)
02. 인터페이스 상속과 인터페이스 인터페이스의 상수 필드 [예제 6-30] 상수 필드가 추가된 대출가능 인터페이스 1 2 3 4 5 6 interface Lendable { final static byte STATE_BORROWED = 1; // 대출 중 final static byte STATE_NORMAL = 0; // 대출되지 않은 상태 void checkOut(String borrower, String date); void checkIn(); }
02. 인터페이스 상속과 인터페이스 인터페이스의 상수 필드 [예제 6-31] 대출가능 인터페이스로부터 상수 필드를 상속받는 단행본 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class SeparateVolume implements Lendable { String requestNo; // 청구번호 String bookTitle; // 제목 String writer; // 저자 String borrower; // 대출인 String checkOutDate; // 대출일 byte state; // 대출상태 SeparateVolume(String requestNo, String bookTitle, String writer) { this.requestNo = requestNo; this.bookTitle = bookTitle; this.writer = writer; } public void checkOut(String borrower, String date) { if (state != STATE_NORMAL) return; this.borrower = borrower; this.checkOutDate = date; this.state = STATE_BORROWED; System.out.println("*" + bookTitle + " 이(가) 대출되었습니다."); System.out.println("대출인:" + borrower); System.out.println("대출일:" + date + "\n"); public void checkIn() { this.borrower = null; this.checkOutDate = null; this.state = STATE_NORMAL; System.out.println("*" + bookTitle + " 이(가) 반납되었습니다.\n"); implements 절 Lendable 인터페이스의 상수 필드를 사용 Lendable 인터페이스의 상수 필드를 사용 Lendable 인터페이스의 상수 필드를 사용
02. 인터페이스 상속과 인터페이스 인터페이스의 상수 필드 [예제 6-32] Lendable 인터페이스의 상수 필드를 사용하는 프로그램 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class InterfaceExample3 { public static void main(String args[]) { SeparateVolume obj = new SeparateVolume("863ㅂ", "나무", "베르베르"); printState(obj); obj.checkOut("이수경", "20060317"); } static void printState(SeparateVolume obj) { if (obj.state == Lendable.STATE_NORMAL) { System.out.println("------------------"); System.out.println("대출상태: 대출가능"); if (obj.state == Lendable.STATE_BORROWED) { System.out.println("대출상태: 대출중"); System.out.println("대출인: " + obj.borrower); System.out.println("대출일: " + obj.checkOutDate); Lendable 인터페이스의 상수 필드를 사용 Lendable 인터페이스의 상수 필드를 사용
02. 인터페이스 상속과 인터페이스 익셉션을 발생하는 추상 메소드 [예제 6-33] checkOut 메소드 밖으로 익셉션을 던지는 단행본 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class SeparateVolume implements Lendable { String requestNo; String bookTitle; String writer; String borrower; String checkOutDate; byte state; SeparateVolume(String requestNo, String bookTitle, String writer) { this.requestNo = requestNo; this.bookTitle = bookTitle; this.writer = writer; } public void checkOut(String borrower, String date) throws Exception { if (state != 0) throw new Exception("*대출불가:" + bookTitle); this.borrower = borrower; this.checkOutDate = date; this.state = 1; System.out.println("*" + bookTitle + " 이(가) 대출되었습니다."); System.out.println("대출인:" + borrower); System.out.println("대출일:" + date + "\n"); public void checkIn() { this.borrower = null; this.checkOutDate = null; this.state = 0; System.out.println("*" + bookTitle + " 이(가) 반납되었습니다.\n"); throws 절 [예제 6-24] 대출 중 상태(0)이면 메소드 밖으로 익셉션을 던집니다.
02. 인터페이스 상속과 인터페이스 익셉션을 발생하는 추상 메소드 [예제 6-34] 추상 메소드에 throws 절을 추가한 대출가능 인터페이스 1 2 3 4 interface Lendable { abstract void checkOut(String borrower, String date) throws Exception ; abstract void checkIn(); } throws 절 [예제 6-34]
상속과 인터페이스 02. 인터페이스 인터페이스의 상속 • 인터페이스의 상속이 필요한 경우의 예
상속과 인터페이스 02. 인터페이스 인터페이스의 상속 • 다른 인터페이스를 상속 받는 인터페이스의 선언 방법
02. 인터페이스 상속과 인터페이스 인터페이스의 상속 [예제 6-35] 위치이동 인터페이스를 상속하는 변환 인터페이스 1 2 3 4 interface Movable { void moveTo(int x, int y); // 절대 위치로 이동한다 void moveBy(int xOffset, int yOffset); // 상대 위치만큼 이동한다 } 상속 변환 인터페이스 1 2 3 interface Transformable extends Movable { void resize(int width, int height); // 크기를 변경한다 }
02. 인터페이스 상속과 인터페이스 인터페이스의 상속 [예제 6-36] 변환 인터페이스를 구현하는 사각형 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Rectangle implements Transformable { int x, y, width, height; Rectangle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } public void resize(int width, int height) { public void moveTo(int x, int y) { public void moveBy(int xOffset, int yOffset) { this.x += xOffset; this.y += yOffset; implements 절 Transformable 인터페이스의 메소드를 구현합니다. Movable 인터페이스의 메소드를 구현합니다.
02. 인터페이스 상속과 인터페이스 인터페이스의 상속 [예제 6-37] Rectangle 클래스를 사용하는 프로그램 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class InterfaceExample4 { public static void main(String args[]) { Rectangle obj = new Rectangle(100, 200, 10, 10); printRectangle(obj); obj.moveTo(25, 35); obj.moveBy(-5, -5); obj.resize(30, 30); } static void printRectangle(Rectangle obj) { System.out.printf("사각형: 위치(%d, %d) 크기(%d x %d) %n", obj.x, obj.y, obj.width, obj.height);
상속과 인터페이스 02. 인터페이스 인터페이스의 다중 상속 • 인터페이스의 다중 상속이 필요한 경우의 예
상속과 인터페이스 02. 인터페이스 인터페이스의 다중 상속 • 다중 상속을 하는 인터페이스의 선언 방법
02. 인터페이스 상속과 인터페이스 인터페이스의 다중 상속 [예제 6-38] 두 개의 인터페이스를 동시에 상속받는 외형변경 인터페이스 크기변경 인터페이스 선언 색상변경 인터페이스 선언 1 2 3 interface Resizable { void resize(int width, int height); } 1 2 3 4 interface Colorable { void setForeground(String color); void setBackground(String color); } 외형변경 인터페이스 선언 1 2 3 interface Changeable extends Resizable, Colorable { void setFont(String font); }
02. 인터페이스 상속과 인터페이스 인터페이스의 다중 상속 [예제 6-39] 외형변경 인터페이스를 구현하는 라벨 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Label implements Changeable { String text; int width, height; String foreground, background; String font; Label(String text, int width, int height, String foreground, String background, String font) { this.text = text; this.width = width; this.height = height; this.foreground = foreground; this.background = background; this.font = font; } public void resize(int width, int height) { public void setForeground(String color) { this.foreground = color; public void setBackground(String color) { this.background = color; public void setFont(String font) { Resizable 인터페이스의 메소드를 구현 Colorable 인터페이스의 메소드를 구현 Changeable 인터페이스의 메소드를 구현
02. 인터페이스 상속과 인터페이스 인터페이스의 다중 상속 [예제 6-40] 라벨 클래스를 사용하는 프로그램 1 2 3 4 5 7 8 9 10 11 12 13 14 class InterfaceExample5 { public static void main(String args[]) { Label obj = new Label("안녕하세요", 100, 30, "yellow", "green", "굴림체"); printLabel(obj); obj.resize(200, 70); obj.setForeground("black"); obj.setBackground("white"); obj.setFont("궁서체"); } static void printLabel(Label obj) { System.out.printf( "%s: %d x %d 배경색(%s) 전경색(%s) 폰트(%s) %n", obj.text, obj.width, obj.height, obj.background, obj.foreground, obj.font);