안녕하세요. 자바 프로그래밍 입문 일곱번째를 달려갑니다.
이번 포스팅에서는 객체지향 프로그래밍이 무엇인지, 그리고 객체지향 프로그래밍의 특징 중 은닉성(캡슐화)에 대해 알아보겠습니다.
이전 포스팅에서는 예외가 무엇인지 그리고 예외 처리를 어떻게 하는지 파일 입출력은 어떻게 하는지 봤었습니다.
우선 이전 포스팅을 복습해 봅시다!
코드를 실행했을 때 예외가 발생할만한 코드를 try
블럭에 넣어주고 예외 발생 시 catch
가 코드 실행을 막고 예외를 띄워줬습니다.
try {
// 예외가 발생할 가능성이 있는 소스코드
} catch (예외 클래스 e) {
// 예외 클래스 메시지 출력
} :
:
:
// catch는 연달아서 계속 쓸 수 있습니다.
} finally {
// 무조건 실행할 구문
// 뒤처리
}
finally
는 의무적이지는 않고 선택사항입니다.
또한 예외를 처리할 때 catch
에 괄호로 예외 클래스를 기록해주는데 하나로 퉁쳐서 Exception e
만 입력해줘도 된다는 것을 살펴보았죠.
파일 입출력을 할 때는 우선 파일이 어디에 존재하는지 또는 어디에 생성할 것인지 디렉터리나 파일명부터 지정해주어야 했습니다.
이 때 File
객체를 사용해서 새로운 객체를 만들었습니다.
File newFile = new File ("/Users/user");
이렇게 지정해주고 이 디렉터리 안에 뭐가 들어있는지 확인하려면
File newFile = new File ("/Users/user");
String fileList = newFile.list();
for (int i = 0; i < fileList.length; i++) {
System.out.println(fileList[i]);
}
이렇게 작성해줍니다. 그러면 디렉터리 안에 있는 파일들을 배열로 리턴해줍니다.
또 다른 메서드로 listFiles()
가 있었습니다. 이것은 마찬가지로 디렉터리 안에 있는 파일들을 배열로 리턴해줍니다.
그리고 isFile()
과 isDirectory()
메서드는 boolean
값을 리턴해주기 때문에 조건문과 함께 사용했습니다.
File fileList[] = file.listFiles(); // listFiles() 메서드는 지정한 경로의 파일들을 리스트화 해줍니다.
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isFile()) { // fileList의 i번째 요소가 파일인 경우
System.out.println("[파일]" + fileList[i].getName());
} else if(fileList[i].isDirectory()) { // fileList의 i번째 요소가 폴더인 경우
System.out.println("[폴더]" + fileList[i].getName());
}
}
또한 다음 메서드들이 있었습니다.
메서드 | 의미 |
---|---|
createNewFile() | 새로운 파일을 만들어 줍니다. |
mkdir() | make directory 새로운 폴더를 만들어 줍니다. |
exists() | 파일의 존재 여부를 확인합니다. |
setReadOnly() | 파일을 읽기 전용으로 만들어 줍니다. (선언하는 것만으로도 읽기전용이 됩니다.) |
delete() | 파일을 삭제해 줍니다. (선언하는 것만으로도 삭제 됩니다.) |
canWrite() | 파일의 쓰기 가능 여부를 알려줍니다. |
파일을 읽을 때는 한 글자씩 읽을 것인지, 문장 단위로 읽을 것인지를 결정해 주어야 합니다.
우선 한글자로 읽을 때는 FileReader
라는 객체를 사용했습니다.
그리고 문장 단위로 읽어줄 때는 BufferedReader
라는 객체를 사용했었습니다.
// 한 글자씩 읽기
File file = new File("/Users/user/myFolder/newFile.txt");
try {
FileReader fr = new FileReader(file);
// 한글자씩 읽기
int ch = fr.read();
while (ch != -1) {
System.out.println((char)ch);
ch = fr.read();
}
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
읽기가 종료되면 close()
메서드를 사용해서 반드시 빠져나와야 합니다.
쓰기를 할 때도 마찬가지 입니다!!
// 한 문장씩 읽기
try {
File file = new File("/Users/user/myFolder/newFile.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while((str = br.readLine()) != null) {
System.out.println(str);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
쓰기를 할 때는 일반적인 쓰기방법이 있었고, 추가적으로 더 기록해주는 방법 그리고 개행이 이루어지는 쓰기 방법이 있었습니다.
새로 만든 문서에 다음과 같은 코드를 실행하면 내용을 입력할 수 있었습니다
File file = new File("/Users/user/myFolder/newFile.txt");
try {
FileWriter fw = new FileWriter(file);
fw.write("안녕하세요");
fw.write("반가워요");
fw.close();
} catch (Exception e) {
e.printStact.Trace;
}
그리고 추가적으로 다른 내용을 쓸 때 위의 방법을 그대로 적용하면 덮어쓰기가 되어 기존에 작성한 내용은 모두 없어지기 때문에 다음과 같은 방법으로 작성해주었습니다.
File file = new File("/Users/user/myFolder/newFile.txt");
try {
FileWriter fw = new FileWriter(file, true); // 여기에 true로 지정해서 추가 쓰기
fw.write("건강하세요");
fw.write("행복하세요");
fw.close();
} catch (Exception e) {
e.printStact.Trace;
}
개행이 이루어지는 쓰기는 준비할게 많았습니다. 세 가지정도?
FireWriter
와 BufferedWriter
그리고 PrintWriter
가 있었습니다.
File file = new File("/Users/user/myFolder/newFile.txt");
try {
FileWriter fw = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new PrintWriter(bw);
pw.println("안녕하세요");
pw.println("만나서 반가워요");
pw.println("잘 부탁합니다");
pw.close(); // 이것만 close해주어도 됩니다.
bw.close();
fw.close();
} catch (Exception e) {
e.printStackTrace();
}
복습 마치고 메인 내용을 살펴봅시다!!
우선 JavaScript를 하셨다면 엄청나게 많이 들어보았을 객체 지향, Java도 마찬가지입니다.
OOP와 POP의 개념에 대해 우선 알아보겠습니다.
OOP : Object Oriented Programming ==> 객체 지향 프로그래밍
POP : Procedure Oriented Programming ==> 절차 지향 프로그래밍
우선 우리가 자바 튜토리얼에서 이제까지 진행해 온 방법은 절차 지향 프로그래밍입니다. 모든 것을 프로그램 구성의 절차에 따라서 코드를 기술했습니다.
우리가 오늘부터 객체지향에 대해 다룬다고는 하지만 객체지향이 절차지향보다 우선시 되거나 하지는 않습니다. 각각의 장단점이 있기 때문에 적절하게 배합해서 사용하는 것이 좋습니다.
절차지향은 객체지향에 비해 속도가 비교적 빠릅니다.
그렇지만 같은 로직을 가진 다양한 객체를 만들어야 하는 경우에는 객체 지향 프로그래밍이 더 효율적이라는 것이죠.
우선 객체 지향 프로그래밍의 특징이 있습니다.
- 은닉성(캡슐화)
- 상속성(프로토타입)
- 다형성
- 추상화
이들 중에서 우리는 이번 포스팅에서 캡슐화에 대해 살펴 볼 것입니다.
자바에서 객체는 클래스라고 합니다. 클래스라는 객체 자료형을 주고 객체의 이름을 붙여주어 내부에 변수가 메서드가 들어갑니다.
// 객체의 형식
class className {
variable; // 변수
method; // 메서드
}
예를 들어서 아래와 같은 클래스 파일을 생성해보겠습니다.
class MyClass {
int number;
String number;
void method() {
System.out.println("MyClass method()");
}
}
그리고 메인 클래스로 돌아와서 객체를 생성해줍시다!
public class Main {
public static void main(String[] args) {
MyClass cls = new MyClass();
}
}
객체는 이렇게 new
생성자를 사용해서 초기화와 선언을 동시해 해 줄 수 있습니다.
배열 같은 경우에는 int[] myArray = new int [4]
처럼 동적할당을 위한 선언 초기화를 해주거나, int[] myArray = { 1, 2, 3, 4 }
처럼 직접 값을 할당하여 선언 및 초기화를 해주었습니다.
객체는 처음 선언해줄 때 new
생성자로 초기화 한다는 사실을 잊지 마세요!
그렇다면 객체지향에 대해 좀 더 이해해 볼 필요가 있습니다.
텔레비전을 예로 들어서 객체지향 프로그래밍에 대해 알아보겠습니다.
TV 두대가 있고 각 TV는 전원의 켜짐/꺼짐 상태, 시청 채널, 볼륨, 제조사를 저장하고 있습니다.
이제까지 우리가 살펴봤던 절차지향의 방식이라면 어떻게 하나요?
// 우선 변수를 지정해줍니다.
boolean[] isPowerOn = new boolean[2];
int[] channel = new int[2];
int[] volume = new int[2];
String maker[] = new String[2];
// 첫번째 TV에 대한 정보를 넣어줍니다.
isPowerOn[0] = true;
channel[0] = 23;
volume[0] = 10;
maker[0] = "Samsung";
// 두번째 TV에 대한 정보를 넣어줍니다.
isPowerOn[1] = false;
channel[1] = 50;
volume[1] = 0;
maker[1] = "LG";
// 배열 안의 내용을 출력해줍니다.
for (int i = 0; i < channel.length; i++) {
System.out.println("TV 제조사는 " + maker[i] + "이고, 상태는 " + isPowerOn[i] + "이고, " + channel[i] + "번을 보고 있으며 볼륨은 " + volume[i] + "입니다.");
}
이렇게 두대의 TV라고 가정했을 때 TV 개수만큼 배열을 만들어주고 원소들을 전부 하나하나 집어넣어줘야 합니다.
그렇다면 객체지향의 경우는 어떨까요?
// TV 클래스를 만들어줍니다.
class TV {
boolean isPowerOn;
int channel;
int volume;
String maker;
void method() {
System.out.println("TV는 제조사는 " + maker + "이며, 상태는 " + isPowerOn + "이고, " + channel + "번을 보고 있으며 볼륨은 " + volume + "입니다.");
}
}
TV 클래스를 우선 지정해줍니다. 안에 변수들이 선언되어있는데, 이처럼 클래스 안의 변수를 클래스의 멤버변수라고 하고, 클래스 안에 선언된 메서드를 멤버 메서드라고 합니다.
그리고 TV의 개수만큼 TV 객체 배열을 만들어주고 그 안에 정보를 밀어넣어주는 것입니다.
TV[] tvArray = new TV[2]; // 이건 배열 생성이지 객체 생성이 아닙니다~ == TV tv1, tv2
for (int i = 0; i < tvArray.length; i++) {
tvArray[i] = new TV(); // 객체 생성
}
tvArray[0].isPowerOn = true;
tvArray[0].channel = 23;
tvArray[0].volume = 10;
tvArray[0].maker = "Samsung";
tvArray[1].isPowerOn = false;
tvArray[1].channel = 50;
tvArray[1].volume = 0;
tvArray[1].maker = "LG";
for (int i = 0; i < tvArray.length; i++) {
tvArray[i].method();
}
TV에 대한 각 정보들은 제각각이기 때문에 어쩔 수 없다는 사실을 감안한다면 이를 제외하고 봤을 때 절차지향보다 코드가 간단해졌습니다.
생성자는 constructor
라고 합니다. 원래 예전에는 이와 반대되는 소멸자 desctuctor
라는 개념도 있었는데 소멸자는 이제 사용하지 않습니다.
객체를 새로 만들어서 초기화할 때 생성자를 사용한다는 사실을 앞에서 언급했습니다.
소멸자라는 것은 이제 Java의 가비지컬렉터라는 기능이 사용하지 않는 변수나 객체를 메모리에서 제외시켜주기 때문에 사용하지 않게 된 것입니다.
그렇다면 생성자가 도대체 무엇일까요? 생성자는 우선 객체 생성시에 한 번 호출되는 녀석입니다. 메서드로 구분하고 클래스명과 같습니다. 또한 return
값이 없습니다. 그리고 overload
가 가능합니다. 생략해도 무방합니다.
생성자
1. 객체 생성 시점에 한번만 호출
2. 메서드임
3.return
값이 없음
4.overload
가능
자 그러면 클래스 파일을 새로 만들어서 MyClass
라는 클래스를 만들어보겠습니다.
public class MyClass {
int number;
String name;
MyClass() {
System.out.println("MyClass의 기본 생성자");
}
}
자 우선 간단한 클래스를 만들어 보았습니다. 멤버 변수로 4바이트 정수형 number
와 문자열 name
울 갖습니다. 그리고 안에 또 MyClass () {... }
이 있습니다. 이것이 바로 생성자 입니다.
보시면 클래스명과 같은 것을 볼 수 있습니다. 멤버 메서드와의 차이는 멤버 메서드의 경우 void...
같은 형식으로 return
이 있는지 없는지를 우선 알려주기 때문에 둘은 서로 다릅니다.
public class MyClass {
int number;
String name;
MyClass() {
System.out.println("MyClass의 기본 생성자");
}
MyClass(int num) {
System.out.println("MyClass(int num) 생성자");
}
MyClass(int num, String na) {
this.number = num;
this.name = na;
System.out.println("MyClass(int num, String na) 생성자");
}
MyClass getThis () {
return this;
}
}
이 코드를 보시면 가인수를 다르게 해서 오버로드가 가능하다는 사실을 알 수 있습니다.
그리고 this
는 매개변수가 멤버변수에 접근할 때 자기 객체의 heap 메모리 주소를 저장해주는 것입니다.
그러니까 this
가 붙어 있는 것은 멤버변수이고, 그렇지 않은 것은 매개변수나 지역변수라고 생각하면 되겠습니다!
자 그러면 메인 클래스로 돌아와서 위에서 작성한 클래스를 사용해보겠습니다.
public class Main {
public static void main(String[] args) {
MyClass cls = new MyClass(); // 클래스 초기화, 객체가 생성되면 기본 생성자를 불러옵니다.
MyClass cls1 = new MyClass(1, "홍길동"); // 이렇게 오버로드 가능
MyClass t = cls.getThis(); // getThis라는 클래스를 호출하여 저장합니다.
System.out.println(t);
}
}
자, 그러면 다음 코드를 사용할 수 있는 클래스를 작성해봅시다.
// Main Class
public class Main {
public static void main(String[] args) {
Student s = new Student();
s.name = "홍길동";
s.ban = 1;
s.no = 1;
s.kor = 100;
s.eng = 60;
s.math = 76;
System.out.println("이름 : " + s.name);
System.out.println("총점 : " + s.getTotal(s.kor, s.eng, s.math));
System.out.println("평균 : " + s.getAverage());
}
}
// Student Class
public class Student {
String name;
int ban;
int no;
int kor;
int eng;
int math;
int total;
int getTotal(int kor, int eng, int math) {
total = kor + eng + math;
return total;
}
double getAverage() {
return (double)total / 3;
}
/* 또 다른 방법
int getTotal(int kor, int eng, int math) {
this.kor = kor;
this.math = math;
this.eng = eng;
int total = kor, math, eng;
return total;
}
double getAverage() {
return (double)(kor + eng + math) / 3;
}
*/
}
캡슐화, 은닉성이라고 하는 것은 객체 지향 프로그래밍의 한 특징입니다. 이는 멤버(멤버변수, 멤버 메서드 등)에 대한 외부 접근을 제어하는 것으로 차단, 읽기전용, 허용여부 결정 등이 있습니다.
여기에서 외부 접근을 제어한다는데 초점을 두어야 합니다.
접근 지정자에는 세개가 있습니다.
접근 지정자 | 의미 |
---|---|
public | 아무 곳에서나 접근할 수 있습니다. |
private | 클래스 내부에서만 접근할 수 있습니다. |
protected | 상속에 따른 보호, 요즘엔 잘 안쓴다고 하네요 |
자 그러면 클래스 파일을 하나 작성해서 각각의 접근 지정자에 대해 자세히 살펴봅시다.
// MyClass
public class MyClass {
private int number;
public String name;
protected double height;
}
// Main
public class Main {
public static void main(String[] args) {
MyClass cls = new MyClass();
cls.number = 1;
}
}
우선 이렇게 작성해주면 불완전한 코드가 됩니다. 왜냐하면 number
는 private
이기 때문에 외부 패키지에서 접근할 수 없기 때문이지요.
외부 패키지에 있는 값을 가져오거나 메인에서 외부에 있는 값을 조정할 때는 getter
와 setter
메서드를 사용합니다.
// MyClass
public class MyClass {
private int number;
public String name;
protected double height;
}
여기에서 getter
메서드와 setter
메서드를 멤버 메서드로 선언해 줄 것입니다.
// MyClass
public class MyClass {
private int number;
public String name;
protected double height;
// setter
public void setNumber(int number) {
this.number = number;
}
// getter
public int getNumber() {
return this.number;
}
}
setter
같은 경우에는 parameter로 값을 받아와서 지정해줘야 하기 때문에 parameter가 존재하지만 getter
의 경우에는 단순히 값을 전달만 하면 되기 때문에 parameter가 없습니다.
getter
와 setter
를 작성해주고 메인 클래스에서 다음과 같이 실행해줍니다.
// Main
public class Main {
public static void main(String[] args) {
MyClass cls = new MyClass();
cls.setNumber(123);
int num = cls.getNumber();
System.out.println(num); // 123
}
}
DTO는 계층간 데이터의 교환을 위한 객체 즉 Java Beans를 말합니다.
로직을 가지지 않는 데이터 객체이며 getter
나 setter
메서드만 가지고 있는 클래스입니다. 주로 비동기 처리를 할 때 사용하지요.
데이터베이스의 데이터에 접근하기 위한 객체입니다. 이 객체로 직접 데이터베이스에 접근하여 데이터를 삭제, 조회, 수정할 수 있습니다.
데이터베이스에 접근을 하기 위한 logic이나 비즈니스 로직을 분리하기 위해서 사용합니다.
VO는 불변 클래스, 즉 Read-Only 속성을 위한 객체입니다.
자바에서는 단순하게 값을 표현하기 위해 불변 클래스를 만들어서 사용하는데, 예를 들어서 보라색을 만든다고 하면 Color.PURPLE처럼 단순한 값이 이에 해당합니다.
값을 가져오기만 하면 되기 때문에 getter
메서드 기능만 존재합니다.
사람의 정보를 담는 DTO 예제를 만들어보겠습니다.
public class MemberDto {
private String name;
private int age;
private String address;
private String phone;
private String content;
public MemberDto() {
this.name = name;
this.age = age;
this.address = address;
this.phone = phone;
this.content = content;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
쪼개서 살펴보면,
private String name;
private int age;
private String address;
private String phone;
private String content;
우선 멤버 변수를 선언해 주었습니다.
public MemberDto() {
this.name = name;
this.age = age;
this.address = address;
this.phone = phone;
this.content = content;
}
그리고 생성자를 통해 멤버변수에 this
바인딩을 적용하여 외부에서 변수를 참조하려고 할 때 heap 메모리 영역을 참조하게 해줍니다.
이하는 getter와 setter 메서드를 만들어주었습니다.
이처럼 DTO에는 로직이 없습니다!
메인에서 어떻게 적용하고 있을까요?
package main;
import dto.MemberDto;
public class Main {
public static void main(String[] args) {
String[][] Member = {
{ "홍길동", "24", "123-4567", "서울시", "동창" },
{ "성춘향", "19", "234-9678", "남원시", "여사친" },
{ "정수동", "22", "345-6789", "인천시", "선배" },
};
MemberDto member[] = new MemberDto[3];
for (int i = 0; i < member.length; i++) {
member[i] = new MemberDto();
}
// 추가
member[0].setName("홍길동");
member[0].setAge(24);
member[0].setPhone("133-0940");
member[0].setAddress("서울시");
member[0].setContent("동창");
// 가져오기
System.out.println(member[0].getName());
System.out.println(member[0].getAge());
System.out.println(member[0].getPhone());
System.out.println(member[0].getAddress());
System.out.println(member[0].getContent());
}
}
우선 2차원 배열을 만들어주었습니다.
그리고 MemberDto
객체를 배열로 잡아 초기화 해줬습니다. 배열에는 3개의 인덱스가 만들어집니다.
member
배열의 i
번째 있는 것을 새로 만든 객체 배열에 넣어줍니다.
그 다음 setter
로 값을 0번째 인덱스의 값을 변경해주고 getter
로 불러오면 변경해 준 값이 들어가 있는 것을 확인할 수 있습니다.
오늘 정리할 내용은 여기까지입니다.
연습문제가 아직 전부 해결이 안돼서 문제와 제가 작성한 로직만 우선 올려두고 따로 포스팅하도록 하겠습니다!
학생 정보를 입력받아 추가, 삭제, 검색, 수정, 모두 출력, 종료할 수 있는 프로그램을 작성하시오.
// Main Class
package main;
import dao.StudentDao;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
StudentDao dao = new StudentDao();
//menu
while(true) {
// CRUD
System.out.println("*************************************");
System.out.println("1. 학생정보 추가");
System.out.println("2. 학생정보 삭제");
System.out.println("3. 학생정보 검색");
System.out.println("4. 학생정보 수정");
// ETC.
System.out.println("5. 학생정보 모두 출력");
System.out.println("6. 종료");
System.out.println("*************************************");
System.out.print("메뉴 번호 입력 >> ");
int menuNum = sc.nextInt();
System.out.println("*************************************");
switch(menuNum) {
case 1:
dao.insert();
break;
case 2:
dao.delete();
break;
case 3:
dao.select();
break;
case 4:
dao.update();
break;
case 5:
dao.alldata();
break;
case 6:
System.exit(0);
break;
}
}
}
}
// DTO
package dto;
public class StudentDto {
private int number;
private String name;
private double height;
private int eng;
private int math;
public StudentDto() {
}
public StudentDto(int number, String name, double height, int eng, int math) {
this.number = number;
this.name = name;
this.height = height;
this.eng = eng;
this.math = math;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public int getEng() {
return eng;
}
public void setEng(int eng) {
this.eng = eng;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
@Override
public String toString() {
return "StudentDto [number=" + number + ", name=" + name + ", height=" + height + ", eng=" + eng + ", math="
+ math + "]";
}
}
package dao;
import dto.StudentDto;
import java.util.Scanner;
// 데이터의 접근, 관리
public class StudentDao {
Scanner sc = new Scanner(System.in);
private final StudentDto[] student = new StudentDto[20];
private int count;
private int wantDel;
public StudentDao() {
count = 0;
student[0] = new StudentDto(1001, "홍길동", 171.1, 90, 85);
student[1] = new StudentDto(1002, "성춘향", 165.3, 100, 90);
student[2] = new StudentDto(1003, "일지매", 182.6, 80, 95);
count = 3;
}
// CRUD
public void insert() { // 학생정보 추가
System.out.print("번호 = ");
int number = sc.nextInt();
System.out.print("이름 = ");
String name = sc.next();
System.out.print("신장 = ");
double height = sc.nextDouble();
System.out.print("영어점수 = ");
int eng = sc.nextInt();
System.out.print("수학점수 = ");
int math = sc.nextInt();
student[count] = new StudentDto(number, name, height, eng, math);
count++;
}
public void delete() { // 학생정보 삭제
for (int i = 0; i < student.length; i++) {
System.out.println((i+1) + ". " + student[i]);
}
System.out.print("삭제할 학생정보 행 번호 입력 >> ");
int delNum = sc.nextInt();
student[delNum-1] = null;
System.out.println("삭제 완료");
}
public void select() { // 학생정보 검색
System.out.print("검색할 학생 이름 입력 >> ");
String name = sc.next();
// 찾기
int index = -1; // 못찾을 경우 대배해서 인덱스넘버 -1로 선언
for (int i = 0; i < student.length; i++) {
StudentDto dto = student[i];
if(dto != null && !dto.getName().equals("")) {
if (dto.getName().equals(name)) {
index = i;
break;
}
}
}
// 출력
if(index == -1) {
System.out.println("데이터를 찾을 수 없음");
} else {
System.out.println(student[index].toString());
}
}
public void update() { // 학생정보 수정
for (int i = 0; i < student.length; i++) {
System.out.println((i+1) + ". " + student[i]);
}
for (int i = 0; i < student.length; i++) {
System.out.print("수정할 학생 행번호 입력 >> ");
wantDel = sc.nextInt();
System.out.println(student[wantDel-1] + "을 수정합니다.");
System.out.println("변경 항목 선택");
System.out.println("1. 번호, 2. 이름, 3. 키, 4. 영어점수, 5. 수학점수");
System.out.print("번호입력 >> ");
int selNum = sc.nextInt();
switch (selNum) {
case 1:
System.out.print("바꿀 내용 입력 >> ");
int changeNum = sc.nextInt();
student[selNum-1].setNumber(changeNum);
break;
case 2:
System.out.print("바꿀 내용 입력 >> ");
String changeName = sc.next();
student[selNum-1].setName(changeName);
break;
case 3:
System.out.print("바꿀 내용 입력 >> ");
double changeHeight = sc.nextDouble();
student[selNum-1].setHeight(changeHeight);
break;
case 4:
System.out.print("바꿀 내용 입력 >> ");
int changeEng = sc.nextInt();
student[selNum-1].setEng(changeEng);
break;
case 5:
System.out.print("바꿀 내용 입력 >> ");
int changeMath = sc.nextInt();
student[selNum-1].setMath(changeMath);
break;
}
break;
}
}
// 전부보기 : 확인용
public void alldata() {
for (int i = 0; i < student.length; i++) {
System.out.println((i+1) + ". " + student[i]);
}
}
}