본문 바로가기

코딩 국비 학원/Do it! 자바 프로그래밍 입문

[Do it! 자바 프로그래밍 입문]ArrayList 클래스, 배열 응용 프로그램, 상속

22.12.12 배운 내용 정리
(ArrayList 클래스, 배열 응용 프로그램, 상속)

 

기존 배열의 단점과 ArrayList

 

기본 배열은 항상 배열 길이를 정하고 시작하는데

배열을 사용하는 중에는 배열 길이를 변경할 수 없기 때문에 코드를 수정해야하고

(ex.100명의 학생을 위한 프로그램을 개발했는데 어느 순간 학생 수가 100명이 넘어간 경우)

배열은 중간에 요소를 비워 둘 수 없기 때문에 배열 요소 위치를 변경해야함.

(ex.중간에 학생 한 명이 전학을 가서 공백이 생긴 경우)

 

이때 객체 배열을 좀 더 쉽게 사용할 수 있도록 자바에서 제공하는 것이 객체 배열 클래스 ArrayList임.

ArrayList 클래스객체 배열을 관리할 수 있는 멤버 변수와 메서드를 제공함.

 

ArrayList 클래스의 주요 메서드

 

※  ArrayList 클래스에서 프로그램을 만들 때 가장 많이 사용하는 메서드

 

메서드 설명
boolean add(E e) 요소 하나를 배열에 추가함. E는 요소의 자료형을 의미함.
int size( ) 배열에 추가된 요소 전체 개수를 반환함.
E get(int index) 배열의 index 위치에 있는 요소 값을 반환함.
E remove(int index) 배열의 index 위치에 있는 요소 값을 제거하고 그 값을 반환함.
boolean isEmpty( ) 배열이 비어 있는지 확인함.

 

add( ) 메서드를 이용하면 배열 길이와 상관없이 객체를 추가할 수 있음.

만일 배열의 길이가 추가될 요소 개수보다 부족하다면 배열을 더 키울 수 있도록 구현되어 있음.

또 배열 중간의 어떤 요소 값이 제거되면 그다음 요소 값을 하나씩 앞으로 이동하는 코드도 이미 구현되어 있음.

 

※ JavaDoc

F1키를 누르면 ArrayList 클래스 설명이 있는 JavaDoc을 볼 수 있음.

자바를 공부하다 모르는 내용이 있을 때 가장 좋은 방법은 자바에서 제공하는 문서인 JavaDoc을 찾아보는 것임.

 

ArrayList 클래스 활용하기

 

ArrayList를 사용할 때 어떤 자료형 객체를 사용하여 프로그래밍할 것인지 선언할 수 있음.

 

ArrayList를 사용하는 기본 형식

ArratList<E> 배열 이름 = new ArrayList<E>( );

배열을 선언하는 부분의 < > 안에 사용할 객체의 자료형(E)을 쓰면 됨.

 

ex. Book 클래스형을 자료형으로 사용해서 ArrayList 배열을 생성한다면 다음과 같음.

ArrayList<Book> library = new ArrayList<Book>( );

ArrayList는 *java.util 패키지에 구현되어 있는 클래스로,

현재 만든 프로그램에는 java.util 패키지가 포함되어 있지 않기 때문에

ArrayList를 사용하기 위해서는 컴파일러에게 ArrayList가 어디에 구현되어 있는지 알려줘야함.

이렇게 내 코드에 없는 클래스를 가져와 사용할 때 이 클래스가 어디에 구현되어 있다고 알려주기 위해

코드 맨 뒤에 선언하는 것을 '임포트 한다'고 함.

ArrayList를 사용하려면 자바 클래스를 선언하기 전 import java.util.ArrayList; 문장을 반드시 써 주어야 함.

 

*java.util 패키지 = 자바에서 사용하는 여러 자료 구조와 알고리즘에 관련된 클래스를 구현해 놓은 패키지

 

ArrayList 클래스 사용하기

 

ArrayList를 생성할 때는 배열 전체 길이를 미리 지정할 필요 없이 add( ) 메서드를 사용해 생성자만 호출하면 됨.

ArrayList는 객체 배열이므로 8~12행과 같이 각 인스턴스를 생성해서 배열의 요소로 추가함.

14~17행은 ArrayList에 있는 인스턴스를 순서대로 가져와서 출력하는 데 이때 요소를 하나 가져오는 메서드는 get( )임.

14행 for문에서는 배열에 추가된 요소 개수만큼만 출력하기 위해  size( ) 메서드를 사용함.

size( ) 메서드는 배열에 유효한 값이 저장된 요소 개수를 반환함.

 


 

※ 학생 성적 출력 프로그램 구현(Student, Subject 클래스 사용)

ex. 어떤 학생이 10과목을 수강한다면 Subject 클래스형을 자료형으로 선언한 변수가 10개 필요함.

또 어떤 학생은 3과목, 다른 학생은 5과목을 수강할 수도 있음.

따라서 이러한 경우에는 배열을 사용하여 프로그램을 구현하는 것이 좋음.

 

※ 예제 시나리오

1001학번 Lee와 1002학번 Kim, 두 학생이 있다. Lee 학생은 2과목을 수강하며, 국어 점수가 100점, 수학 점수가 50점임.

Kim 학생은 3과목을 수강하며, 국어 점수가 70점, 수학 점수가 85점, 영어 점수가 100점임.

이때 Student 클래스와 Subject 클래스를 생성한 후 두 학생의 과목 성적과 총점을 각각 출력하기

 

Student 클래스 구현

 

성적 출력 프로그램은 어떤 학생이 수강하는 과목들의 성적을 출력하는 것이므로 '학생'객체가 필요함.

 

Sudent 클래스 구현

 

한 학생이 수강하는 과목은 여러 개 있을 수 있으므로, subject 클래스형으로 ArrayList를 생성함.

subjectList는 학생이 수강하는 과목을 저장할 배열임.

학생의 수강 과목을 하나씩 추가하기 위해 addSubject( ) 메서드를 만듦.

매개변수로 넘어온 과목 이름과 점수를 가지고 Subject 클래스를 생성하고, 생성한 인스턴스는 subjectList에 추가함.

그럼 학생의 수강 과목 정보는 subjectList에 저장됨.

 

Subject 클래스 구현

 

Subject 클래스는 과목 정보를 담음.

Subject 클래스의 멤버 변수는 과목 이름과 성적 두 가지임.

 

Subject 클래스 구현

 

테스트 클래스 구현 후 결과 확인

 

학생 두 명을 생성하고 각 학생의 과목별 성적과 총점 출력

 

학생 성적 출력

 


 

클래스의 상속

 

상속 = 무엇인가를 물려받는 것

ex. B클래스가 A클래스를 상속받으면 B클래스는 A 클래스의 멤버 변수와 메서드 사용 가능.

 

클래스간 상속을 표현할 떄는 상속받는 클래스에서 상속하는 클래스로 화살표가 감.

상속하는 클래스 = 부모 클래스 = 상위클래스

상속받는 클래스 = 자식 클래스 = 하위 클래스

 

※ 클래스 상속 문법

자바 문법으로 상속을 구현할 때는 '연장, 확장하다'는 의미의 extends 예약어를 사용함.

즉 A가 가지고 있는 속성이나 기능을 추가로 확장하여 B 클래스를 구현한다는 뜻임.

ex. class B extends A { }     //'B 클래스가 A 클래스를 상속받는다'라고 함

 

상속 관계에서는 상위 클래스가 하위 클래스보다 일반적인 개념이고, 하위 클래스는 상위 클래스보다 구체적인 클래스임.

ex. 포유류는 사람보다 일반적인 개념임. 즉 사람은 포유류의 특징과 기능을 기본으로 더 많거나 다른 특징과 기능을 가짐.

Class Human extends Mammal { }  //사람이 포유류를 상속받음

 

상속을 사용하여 고객 관리 프로그램 구현

 

고객 관리 프로그램을 구현하려면 우선 고객 클래스가 필요함.

그리고 고객 클래스를 구현하려면 클래스 속성을 멤버 변수로 선언하면됨.

(속성 = 고객, 아이디, 이름, 고객 등급, 보너스 포인트 적립 비율)

 

Customer 클래스 구현

 

※ 예제에서 사용한 멤버 변수

 

멤버 변수 설명
CustomerID 고객 아이디
CustomerName 고객 이름
CustomerGrade 고객 등급
기본 생성자에서 지정되는 기본 등급은 SILVER임
bonusPoint 고객의 보너스 포인트
- 고객이 제품을 구매할 경우 누적되는 보너스 포인트
bonusRatio 보너스 포인트 적립 비율
- 고객이 제품을 구매할 때 구매 금액의 일정 비율이 보너스 포인트로 적립됨. 이때 계산 되는 적립 비율.
- 기본 생성자에서 지정되는 적립 비율은 1%임. 즉 10,000원짜리를 사면 100원이 적립됨.

 

※ 예제에서 사용한 메서드

 

메서드 설명
Customer( ) 기본 생성자로, 고객 한 명이 새로 생성되면 CustomerGrade는 SILVER이고,
bonusRatio는 1%로 지정함.
calcPrice(int price) 제품에 대해 지불해야 하는 금액을 계산하여 반환함. 할인되지 않는 경우 가격을 그대로 반환함.
그리고 가격에 대한 보너스 포인트 비율을 적용하여 보너스 포인트를 적립함.
showCustomerInfo( ) 고객 정보를 출력함. 고객 이름과 등급, 현재 적립된 포인트를 보여줌.

 

※ 새로운 고객 등급이 필요한 경우

ex.고객이 점점 늘어나고 판매도 많아지다 보니 단골 고객이 생김. 단골 고객은 회사 매출에 많은 기여를 하는 우수 고객임.

우수 고객 등급은 VIP이고, 다음과 같은 혜택을 제공함.

① 제품을 살 때는 항상 10% 할인해 줌.

② 보너스 포인트를 5% 적립해 줌.

③ 담당 전문 상담원을 배정해 줌

 

이 요구 사항을 구현할 때 이미 Customer 클래스가 존재하므로 해당 클래스에 VIP 고객에게 필요한 변수와 메서드까지 함께 포함하여 구현하는 것이 간단하긴 하지만 이렇게 하면 Customer 클래스 코드가 복잡해짐.

이러한 경우는 VIPCustomer 클래스를 따로 만드는 것이 좋음.

 

VIPCustomer 클래스 구현

 

VIPCustomer 클래스를 구현했는데 앞에서 만든 Customer 클래스와 겹치는 멤버 변수와 메서드가 보임.

게다가 calcPrice( ) 메서드는 이름은 같은데 구현 내용은 다름.

VIP 고객은 일반 고객에게 제공하는 혜택은 기본으로 제공하고 거기에 추가 속성과 메서드가 있는 것임.

바로 이런 경우에 상속을 사용함.

 

VIPCustomer 클래스 구현 2

 

VIPCustomer 클래스의 코드가 간단해짐 → 상속받은 메서드는 구현하지 않았기 때문

그런데 이 코드에는 두 가지 문제가 있음.

①  customerGrade 변수에서 오류가 발생함

→ 상위 클래스에서 private 변수이기 때문에 외부 클래스에서 변수 사용 불가능

② VIP 고객에게 제공하는 혜택인 할인율과 세일 가격을 어떻게 적용할지 구현하지 않음.

 

※ 상위 클래스 변수를 사용하기 위한 protected 예약어

protected 예약어 = 상위 클래스에서 작성한 변수나 메서드 중 외부 클래스에서 사용할 수 없지만

하위 클래스에서는 사용할 수 있도록 지정하는 예약어.

즉 protected는 상속된 하위 클래스를 제외한 나머지 외부 클래스에서는 private와 동일한 역할을 함.

 

protected 변수 선언

 

위와 같이 protected로 선언하면 VIPCustomer 부분의 오류는 사라짐.

 

※ 테스트 프로그램 실행하기

ex.일반 고객 1명과 VIP 고객 1명이 있음.

일반 고객 이름은 이순신이고, 아이디는 10010이며, 현재 보너스 포인트 1000점이 있음.

VIP 고객의 이름은 김유신이고, 아이디는 10020이고, 현재 보너스 포인트 10000점을 가지고 있음.

 

상속 클래스 테스트