냉장고 시스템
객체와 객체의 관계를 중심으로 냉장고 시스템을 객체로 설계해보자.
냉장고시스템을 구현하기 위해서는 다음의 객체들이 필요할 것이다.
- Food(음식)
- Refrigerator(냉장고)
- MainClass(사용자 UI, 프로그램의 시작점)
"Food" Class
public class Food {
String name;
String shelfLife;
String country;
int gram;
public Food(String name, String shelfLife, String country, int gram) {
super();
this.name = name;
this.shelfLife = shelfLife;
this.country = country;
this.gram = gram;
}
}
"Refrigerator" Class
- 필드(food, model, height, width, volume, temperature) 와 생성자(초기값을 받는) 생성
- 메소드(온도내리기, 온도올리기, 음식확인, 음식정보확인), 기능을 추가한다.
public class Refrigerator {
Food[] food;
String model;
int height;
int width;
int volume;
int temperature;
public Refrigerator(Food[] food, String model, int height, int width, int volume, int temperature) {
super();
this.food = food;
this.model = model;
this.height = height;
this.width = width;
this.volume = volume;
this.temperature = temperature;
}
public void upTemperature() {
this.temperature++;
}
public void downTemperature() {
this.temperature--;
}
public void checkFood(String name) {
for(int i = 0; i < food.length; i++) {
if(food[i].name.equals(name)) {
System.out.println(name + "(이)가 존재합니다.");
}
}
}
public void viewFoodInfo(String name) {
for(int i = 0; i < food.length; i++) {
if(food[i].name.equals(name)) {
System.out.println("이름 \t 유통기한 \t 원산지 \t 무게");
System.out.println(food[i].name + "\t" + food[i].shelfLife + "\t " + food[i].country + "\t " + food[i].gram);
}
}
}
}
"Main" Class
- Food 객체 생성 뒤 Food 배열에 넣기
- 냉장고 객체 생성
- 냉장고의 메소드 checkFood()와 viewFoodinfo() 를 통해 음식물 정보 확인
public class RefrigeratorMain {
public static void main(String[] args) {
Food apple = new Food("사과", "2017-10-05", "KOR", 500);
Food banana = new Food("바나나", "2017-09-30", "BRA", 1500);
Food bacon = new Food("베이컨", "2017-11-16", "DEU", 800);
Food[] food = new Food[3];
food[0] = apple;
food[1] = banana;
food[2] = bacon;
Refrigerator ref = new Refrigerator(food, "삼성", 1500, 800, 180, 8);
ref.checkFood("베이컨");
ref.viewFoodInfo("베이컨");
}
}
OOP 의 개념(복습)
OOP 특징
- 추상화
- 캡슐화(Open API를 활용하는 관점에서)
- 상속
많은 입문서에서 매우 중요하게 다뤄지는 부분이지만, 실제 중요성은 그만큼 크지 않다고 한다. - 다형성
객체 구성 요소
- Field (Property)
- Method (Behavior)
생성자, constructor
생성자 (이전 시간에 이어서) 의 특징은 다음과 같다.
- 생성자는 메소드이다.
- 생성자는 하나 이상 선언되어야 한다(디폴트 생성자).
오버로딩 (메소드의 중복정의)
함수의 signature 가 다르면 컴파일러는 함수의 이름이 같더라도 해당 함수를 구별할 수 있다.
같은 이름으로 여러 기능을 정의할 수 있다.
접근제한자 private 그리고 getter 와 setter
캡슐화의 관점에서 접근제한자를 이해하도록 하자.
프로그래머의 실수를 방지해준다는 의미에서 pirvate 이 유용했다. 그러한 의미에서 getter, setter 를 쓰는 이유를 이해한다.
※ 모든 코드는 필요에 의해서 작성되어야 한다.
Q. getter 와 setter 를 쓰는 이유는!?
A. 데이터를 보호하는 의미에서, 또한 getter 와 setter 메소드 내부에서 데이터 강제, 보안 관련 로직을 추가할 수 있다.
ex) 점수가 0부터 100점까지만 강제해야 하는 경우
학생관리프로그램
학생을 등록하고 조회하는 기능을 갖는 시스템을 구축해보자.
Q. 어떤 클래스가 필요할까? (대부분의 관리 시스템이 동일하다는 사실을 상기하자.)
A. 학생 class, 메인 class, 관리시스템 class
프로그래밍을 하는 2가지 방법
- 만들어가다 보니 이런 클래스가 필요하여 그 클래스를 뽑아내는 케이스
- 처음부터 모든 속성과 기능들을 정의하여 계획대로 작성하는 케이스
학생관리 프로그램 클래스 설계
학생 클래스
- Field
- 이름, 학번, 국어, 수학, 영어
- Method
- 학생 등록, 학생 조회, 종료
if 문으로 null 일 때 실행시켜주지 않아도 되지만, 학생 데이터가 추가됨에 따라 index 가 증가하게 해두었으므로 index 만큼만 돌 수 있도록 한다. 만약 null 인데도 불구하고 null 의 메소드를 호출하려고 한다면, 아무것도 없는(null) 객체의 메소드를 호출한다는 의미이므로 NullPointerException
이 발생한다. NullPointerException
아무것도 없는 데이터의 멤버(속성이나 메소드)에 접근하려고 할 때 발생한다.
package StudentGrade;
public class StudentInfo {
private String name;
private String studentNum;
private int mathGrade;
private int engGrade;
private int korGrade;
public StudentInfo(String name, String studentNum, int mathGrade, int engGrade, int korGrade) {
super();
this.name = name;
this.studentNum = studentNum;
this.mathGrade = mathGrade;
this.engGrade = engGrade;
this.korGrade = korGrade;
}
public String getName() {
return name;
}
public String getStudentNum() {
return studentNum;
}
public int getMathGrade() {
return mathGrade;
}
public int getEngGrade() {
return engGrade;
}
public int getKorGrade() {
return korGrade;
}
@Override
public String toString() {
return "Name: " + name + "\t Number: " + studentNum + "\t Math Grade: " + mathGrade + "\t English Grade: " + engGrade + "\t Korean Grade: " + korGrade;
}
}
toString() 오버라이딩(Overriding)
오버라이딩이란, 부모의 객체에서 정의된 메소드의 기능을 부모를 상속받은 자식이 해당 기능을 다시 정의하는 것이다. JAVA 의 모든 객체는 최상위 객체인 Object
클래스를 상속받는데, 이 Object
클래스에 toString()
이 정의되어있다. toString()
메소드는 객체의 정보를 String
형태로 반환하는 메소드인데, 기본적으로 객체의 hashCode
를 출력하는 것이다. System.out.println(car)
와 ㄱ같이 함수에 객체(car)를 인자로 전달하면, 객체의 toString()
이 먼저 호출되고, 그렇게 return 된 string 이 console 창에 찍히게 된다.
하지만 우리는 toString()
이 객체의 hash 코드가 아니라, 학생들의 정보를 console 창에 출력되게 하고 싶으므로, toString()
이라는 메소드를 다시 정의 곧, 오버라이딩 하기로 한다.
이렇게 toString()
메소드를 재정의(overriding)
해놓으면 객체를 print 했을 때 주소가 아닌 toString() 메소드가 실행된다.
관리시스템 클래스
- 등록 불가 판단 부분
- 입력받은 정보를 객체화하여 객체배열에 저장하는 부분
- 출력부분
위 기능을 하는 코드를 따로 빼주자. (UI 저장 기능이 아니라면 managementSystem 으로 이동하자는 것이 기본 아이디어)
StudentMain.java
package StudentGrade;
import java.util.Scanner;
public class Studnet {
public static void main(String[] args) {
StudentManagementSystem sm = new StudentManagementSystem();
System.out.println("===== 학생관리 프로그램 =====");
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("1.등록 2.조회 3.종료 >> ");
int choice = sc.nextInt();
if (choice == 1) {
if (sm.isCanAddStudent()) {
System.out.print("이름 : ");
String name = sc.next();
System.out.print("학번 : ");
String stuNum = sc.next();
System.out.print("수학점수 : ");
int mathScore = sc.nextInt();
System.out.print("영어점수 : ");
int engScore = sc.nextInt();
System.out.print("국어점수 : ");
int korScore = sc.nextInt();
sm.addStudent(name, stuNum, mathScore, engScore, korScore);
} else {
System.out.println("등록인원 초과");
}
} else if (choice == 2) {
StudentInfo[] stuList = sm.getStuList();
for (int i = 0; i < sm.getIndex(); i++) {
System.out.println((i + 1) + "번 학생 >> " + stuList[i]);
// System.out.println("이름 \t 학번 \t 수학 \t 영어 \t 국어");
// System.out.println(stuList[i].getName() + " \t " + stuList[i].getStudentNum()
// + " \t "
// + stuList[i].getMathGrade() + " \t\t " + stuList[i].getEngGrade() + " \t\t "
// + stuList[i].getKorGrade());
}
} else if (choice == 3) {
break;
} else {
System.out.println("잘못된 입력");
}
}
}
}
StudentManagement.java
package StudentGrade;
public class StudentManagementSystem {
private StudentInfo[] stuList = new StudentInfo[3];
private int index = 0;
public boolean isCanAddStudent() {
return index < stuList.length;
}
public void addStudent(String name, String stuNum, int mathScore, int engScore, int korScore) {
stuList[index++] = new StudentInfo(name, stuNum, mathScore, engScore, korScore);
}
public StudentInfo[] getStuList() {
return stuList;
}
public int getIndex() {
return index;
}
}
ArrayList
ArrayList
는 배열과 상당히 유사한 개념이다. 단, 가장 큰 차이점은, 배열은 길이를 조절할 수 없는데, ArrayList
는 길이가 조절된다. 그래서 가변길이배열 이라는 이름으로 불리기도 한다.
컬렉션, Collection
이렇게, 데이터를 일련의 묶음으로 관리하고자 하는 개념을 컬렉션(Collection)
이라고 한다. JAVA 에서는 컬렉션
이라는 이라는 이름을 사용하지만, 다른 이름으로 자료구조(Data Structure)
라고 부르기도 한다.
대표적으로 배열형 데이터를 다루는 ArrayList
, 집합(수학에서의 집합과 유사)데이터를 다루는 HashSet
, 사전식으로 key-value 형식으로 데이터를 매칭시키는 Map
이 있다.
ArrayList
는 다음과 같이 사용한다.
ArrayList<String> list = new ArrayList<>();
ArrayList의 메소드
add
데이터를 추가한다.get
데이터를 추출한다.size
ArrayList의 길이를 추출한다.remove
데이터를 제거한다.clear
ArrayList를 초기화한다.
이외에도 많은 기능이 있으며 추후에 Collection 에 더욱 자세히 알아보는 시간을 갖도록 하자.
JAVA ArrayList 예제
import java.util.ArrayList;
public class ArrayListExmample {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
//추가 add
list.add("hello");
list.add("hello2");
list.add("hello3");
list.add("hello4");
//출력 get
String str = list.get(3);
System.out.println(str);
//길이 size(배열에서 length)
int size = list.size();
System.out.println(size);
//삭제 remove
list.remove(1);
System.out.println(list.size());
//수정 set
list.set(0, "apple");
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//전체 삭제 clear
list.clear();
System.out.println(list.size());
}
}
'2017 SMHRD 노트' 카테고리의 다른 글
JAVA 크롤러 만들기 2 - 리뷰 크롤링, 이미지 IO, 웹툰 크롤링 (0) | 2018.06.05 |
---|---|
JAVA 크롤러 만들기 1 - 뉴스 기사 크롤링 (0) | 2018.06.05 |
JAVA 영화 예매 프로그램, 상속실습, 추상메소드 (0) | 2018.05.31 |
JAVA 외부 API 활용, MP3 플레이어, MVC 패턴 (0) | 2018.05.31 |
JAVA 배열, 2차원 배열 (0) | 2018.05.21 |