안녕하세요. 자바 프로그래밍 입문 일곱번째를 달려갑니다.

이번 포스팅에서는 객체지향 프로그래밍이 무엇인지, 그리고 객체지향 프로그래밍의 특징 중 은닉성(캡슐화)에 대해 알아보겠습니다.

이전 포스팅에서는 예외가 무엇인지 그리고 예외 처리를 어떻게 하는지 파일 입출력은 어떻게 하는지 봤었습니다.

우선 이전 포스팅을 복습해 봅시다!

이전 포스팅 복습


예외처리 방법

코드를 실행했을 때 예외가 발생할만한 코드를 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;
}

개행이 이루어지는 쓰기는 준비할게 많았습니다. 세 가지정도?

FireWriterBufferedWriter 그리고 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 ==> 절차 지향 프로그래밍

우선 우리가 자바 튜토리얼에서 이제까지 진행해 온 방법은 절차 지향 프로그래밍입니다. 모든 것을 프로그램 구성의 절차에 따라서 코드를 기술했습니다.

우리가 오늘부터 객체지향에 대해 다룬다고는 하지만 객체지향이 절차지향보다 우선시 되거나 하지는 않습니다. 각각의 장단점이 있기 때문에 적절하게 배합해서 사용하는 것이 좋습니다.

절차지향은 객체지향에 비해 속도가 비교적 빠릅니다.
그렇지만 같은 로직을 가진 다양한 객체를 만들어야 하는 경우에는 객체 지향 프로그래밍이 더 효율적이라는 것이죠.

우선 객체 지향 프로그래밍의 특징이 있습니다.

  1. 은닉성(캡슐화)
  2. 상속성(프로토타입)
  3. 다형성
  4. 추상화

이들 중에서 우리는 이번 포스팅에서 캡슐화에 대해 살펴 볼 것입니다.

객체의 형식

자바에서 객체는 클래스라고 합니다. 클래스라는 객체 자료형을 주고 객체의 이름을 붙여주어 내부에 변수가 메서드가 들어갑니다.

// 객체의 형식

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 두대가 있고 각 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;
    }
    */
}

Encapsulation : 캡슐화, 은닉성

기본 개념

캡슐화, 은닉성이라고 하는 것은 객체 지향 프로그래밍의 한 특징입니다. 이는 멤버(멤버변수, 멤버 메서드 등)에 대한 외부 접근을 제어하는 것으로 차단, 읽기전용, 허용여부 결정 등이 있습니다.

여기에서 외부 접근을 제어한다는데 초점을 두어야 합니다.

접근 지정자

접근 지정자에는 세개가 있습니다.

접근 지정자의미
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;

    }
}

우선 이렇게 작성해주면 불완전한 코드가 됩니다. 왜냐하면 numberprivate이기 때문에 외부 패키지에서 접근할 수 없기 때문이지요.

외부 패키지에 있는 값을 가져오거나 메인에서 외부에 있는 값을 조정할 때는 gettersetter 메서드를 사용합니다.

// 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가 없습니다.

gettersetter를 작성해주고 메인 클래스에서 다음과 같이 실행해줍니다.

// 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, DAO, VO


DTO(Data Transfer Object)

DTO는 계층간 데이터의 교환을 위한 객체 즉 Java Beans를 말합니다.

로직을 가지지 않는 데이터 객체이며 gettersetter메서드만 가지고 있는 클래스입니다. 주로 비동기 처리를 할 때 사용하지요.

DAO(Data Access Object)

데이터베이스의 데이터에 접근하기 위한 객체입니다. 이 객체로 직접 데이터베이스에 접근하여 데이터를 삭제, 조회, 수정할 수 있습니다.

데이터베이스에 접근을 하기 위한 logic이나 비즈니스 로직을 분리하기 위해서 사용합니다.

VO(Value Object)

VO는 불변 클래스, 즉 Read-Only 속성을 위한 객체입니다.

자바에서는 단순하게 값을 표현하기 위해 불변 클래스를 만들어서 사용하는데, 예를 들어서 보라색을 만든다고 하면 Color.PURPLE처럼 단순한 값이 이에 해당합니다.

값을 가져오기만 하면 되기 때문에 getter 메서드 기능만 존재합니다.

DTO 예시

사람의 정보를 담는 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로 불러오면 변경해 준 값이 들어가 있는 것을 확인할 수 있습니다.

오늘 정리할 내용은 여기까지입니다.

연습문제가 아직 전부 해결이 안돼서 문제와 제가 작성한 로직만 우선 올려두고 따로 포스팅하도록 하겠습니다!


연습문제

문제 1

학생 정보를 입력받아 추가, 삭제, 검색, 수정, 모두 출력, 종료할 수 있는 프로그램을 작성하시오.


// 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]);
        }
    }


}
profile
tried ? drinkCoffee : keepGoing;

0개의 댓글