본문 바로가기
Computer Science/JAVA

[JAVA] 상속이란? (+ 서점 구현하기)

by 그적 2020. 10. 6.

서점 프로그램에서 기준이 되는 Book 클래스에서 어떠한 기능들을 추가로 상속할 것인가?

1) Ebook 클래스를 만들어 Book 클래스를 상속

2) Appendix 클래스를 만들어 Book 클래스를 상속

 

추가로 이번 서점 프로그램 구현에는 파일을 통해 입력을 할 것이다.

 

파일 입력 메서드

// BookStore 클래스의 openFile(String filename) 메서드

   Scanner openFile(String filename) {
      Scanner filein = null;
      try {
         filein = new Scanner(new File(filename));
      }catch(IOException e) {
         System.out.printf("파일을 열수없습니다. - %s", filename);
         System.exit(0);
      }
      return filein;
   }

// BookStore 클래스의 read 메서드

void read(){
	try{
		Scanner filein = openFile(filename);
		Student b = null;
		while(finein.hasNext()){
			b = new Book();
			b.read(filein);		// 파일 스캐너를 매개변수로 넘겨준다.
			bookList.add(b);
		}
		filein.close();
	}catch(Exception e){
		System.out.printf("파일 오픈 실패 : %s\n", filename);
		System.exit(0);
	}
}

특히 read() 메서드에서 필수 사항은 while(filein.hasNext()) 코드를 통해 파일의 끝을 만나면 거짓을 반환하는 부분이다.

 

(파일 입력 시 주의사항)

- 파일 위치 : 프로젝트 홈 디렉터리에 존재

- 파일 포맷이 UTF-8인지를 확인

- 데이터 형식 확인 : 형식이 올바르지 않으면 inputMismatch 오류가 발생한다.

- 마지막 빈 줄 제거 : 데이터 끝에 빈 줄이 있으면 inputMismatch 오류가 발생한다.

- 파일 스캐너를 모두 사용하고 나서는 close()를 필수로 해준다.

 

 

 

 

상속이란?
- 부모 클래스의 필드와 메서드를 물려받음(private 제외)
- 필드나 메서드를 추가로 정의할 수 있음

메서드 오버라이드
- 동일한 이름과 시그너처와 메서드를 다시 정의
- 부모의 것을 대신함

Book 클래스의 상속
(추가될 데이터)
- 전자책 : url, 포맷
- 부록 책 : 부록수, 부록 이름

 

 

Book 클래스

// read(), print(), print_type(), matches() 메서드를 지닌다.

package hw5_book;

import java.util.ArrayList;
import java.util.Scanner;

public class Book{
	
	String title;
	String publisher;
	int isbn;
	int year;
	ArrayList<String> authors = new ArrayList<>();
	int price;
	
	public void read(Scanner s) {
		title = s.next();
		publisher = s.next();
		isbn = s.nextInt();
		year = s.nextInt();
		String tmp;
		
		while(true) {
			tmp = s.next();
			if(tmp.contentEquals("0")) break;
			authors.add(tmp);
		}
		price = s.nextInt();
	}
	
	void printBookType() {
		System.out.print("[일반책]");
	}
	
	public void print() {
		printBookType();
		System.out.printf("%s %s(%d/%d년) %d원 ", title, publisher, isbn, year, price);
		for(String auth: authors)
			System.out.printf("%s", auth);
		System.out.println();
	}

	public boolean matches(String kwd) {
		// TODO Auto-generated method stub
		if(title.contains(kwd)) return true;
		if(publisher.contains(kwd)) return true;
		if(kwd.contentEquals(""+isbn)) return true;
		if(kwd.contentEquals(""+year)) return true;
		
		for(String auth: authors)
			if(kwd.contentEquals(auth))
				return true;
		return false;
	}

}

 

 

 

(상속) Ebook 클래스

Book 클래스를 extends 해주고, print(), read() matches 메서드를 overriding 해준다.

package hw5_book;

import java.util.Scanner;

public class Ebook extends Book{

	String url;
	String format;
	
	void printBookType() {
		System.out.print("[전자책]");
	}
	
	@Override
	public boolean matches(String kwd) {
		if(kwd.contentEquals("전자책")) return true;
		if(super.matches(kwd)) return true;
		if(url.contains(kwd)) return true;
		if(format.contains(kwd)) return true;
		return false;
	}
	
	@Override
	public void read(Scanner s) {
		super.read(s);
		url = s.next();
		format = s.next();
	}
	
	@Override
	public void print() {
		super.print();
		System.out.printf("\t%s [%s]\n", url, format);
	}
}

 

(상속) Appendix 클래스

Book 클래스를 extends 해주고, print(), read() matches 메서드를 overriding 해준다.

package hw5_book;

import java.util.ArrayList;
import java.util.Scanner;

public class Appendix extends Book {
   
   ArrayList<String> appendix = new ArrayList<>();
   
   public void printBookType(){
      System.out.print("[부록책]");
   }

   @Override
   public void read(Scanner s) {
      super.read(s);
      
      int n = s.nextInt();
      
      for(int i=0; i<n; i++) {
         String tmp = s.next();
         appendix.add(tmp);
      }
   }

   @Override
   public void print() {

      super.print();
      System.out.print("\t별책 : ");
      for(String app: appendix)
         System.out.printf("%s ", app);
      System.out.println();
   }

   @Override
   public boolean matches(String kwd) {
      if(kwd.contentEquals("부록책")) return true;
      if(super.matches(kwd)) return true;
      for(String app: appendix)
         if(app.contains(kwd)) return true;
      
      return false;
      
   }

}

 

 

업 캐스팅?

: 상속의 업 캐스팅은 참조 변수의 다형성이라고도 불리며, 슈퍼 클래스의 참조 변수로 상속 객체를 가리킬 수 있다.

ArrayList<Book> booklist = ... ;
Book b = new Ebook();
bookList.add(b);

b = new Book();
bookList.add(b);		// b가 Ebook일 수도 있고, 부록책일 일수도 있고, 책도 될 수 있다.

이러한 경우에 bookList에는 Book객체와 Ebook 객체가 섞여있다. 하지만 이를 구별할 필요가 없는데, 가상 함수를 호출하여 b.print(); 를 사용하게 되면, Book 객체면 일반 기본 정보들만 출력되고, Ebook 객체면 일반 기본 정보에 url과 포맷까지 출력된다.

 

상속이 섞여있는 데이터 입력하기

// switch-case문을 통해 type에 따라 각각의 객체를 생성한다.

void readAllBooks(String filename)
{
	Scanner filein = openFile(filename);
	Book b = null;
	while(filein.hasNext()){
		int n = filein.nextInt();
		switch(n){
		case 1: b = new Book(); break;
		case 2: b = new Ebook(); break;
		default : break;
		}
		b.read(filein);
		bookList.add(b);
	}
}

 

'Computer Science > JAVA' 카테고리의 다른 글

[JAVA] 제너릭이란?  (0) 2020.11.03
[JAVA] 추상화란?  (0) 2020.10.23
[JAVA] 인터페이스란? (+서점 구현하기)  (0) 2020.10.06
[JAVA] 변수와 메서드  (0) 2020.09.11
[JAVA] 자바 기본  (0) 2020.09.02

댓글