열심히 끝까지

디바이스 융합 자바(Java) day08 - 힙,스택,this.,this(),인스턴스 변수,클래스 변수, 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day08 - 힙,스택,this.,this(),인스턴스 변수,클래스 변수,

노유림 2022. 6. 16. 17:23

[지난 수업]
클래스
객체지향 프로그래밍(코딩)
   : 대상체를 갖고 싶어 함
   -> 클래스를 잘 정의(파악)하는 것
   ex) Car클래스 생성!
    >> 어떤 값들을 저장할 수 있는가?
        - 주인(name)
        - 현재 속도 0(speed)
        - 최고 속도 200(maxspeed)
       > name, speed, maxspeed : 멤버변수, 속성, 필드, 어드리뷰트(애트리뷰트)
    >> 어떤 행동들을 수행할지(기능 수행)? : 괄호 포함(함수, 메서드)
        - 속도++()
        - 속도--()
        - 현재 상태를 출력()
     속도를 증가시키는 코드
 
      void speedUp() { // 멤버함수, 메서드
// 1. 기본형
// 2. 기능구현
// 3. input, output이 올바른지 체크
//  -> 값을 받을 필요도, 돌려줄 필요도 없기 때문에 바꿀 것 없음!
speed += 10;
             if(this.speed>this.maxSpeed) {
this.speed=this.maxSpeed;
System.out.println("과속!");
}
      }
      void speedUp(int speed) {
// 기본형 -> 기능 구현 -> input, output이 올바른지 체크
this.speed += speed; // 멤버변수 파란색, 통상변수 갈색  
              if(this.speed>this.maxSpeed) {
this.speed=this.maxSpeed;
System.out.println("과속!");
}
      }
       >> speedUp() 오버로딩★

       Car car1 = new Car(); // 기본(디폴트) 생성자
        : 멤버변수가 내가 원하는 값대로 초기화되지 않는다.
        : 그래서 다음과 같이 만들고 싶어짐
                             ↓
       Car car1 = new Car("홍길동", 0, 200);
        -> 생성자를 사용하는 이유 : 멤버변수를 원하는 값으로 초기화 가능 + "강제"

      이 형태를 사용하기 위해서는 위에 생성자를 만들어주어야 함


        ex ) Car(String name, int speed, int maxSpeed){
                     this.name = name;
                     this.speed = speed;
                     this.maxSpeed = maxSpeed;
              }
              Car(String name){
                     this.name = name;
                     this.speed = 0;
                     this.maxSpeed = 200;
              }
              >> 이렇게 생성자의 이름이 같지만 형태가 달라 두 개 이상 생기게 된 이 것
                   "생성자 오버로딩"이라고 한다.

 

---------- 올코딩
package class01;

class Car{
       String name; // 멤버변수, 속성, 필드, 어트리뷰트
       int speed;
       int maxSpeed;
       void speedUp() { // 멤버함수, 메서드
              // 1. 기본형
              // 2. 기능구현
              // 3. input, output이 올바른지 체크
              //  -> 값을 받을 필요도, 돌려줄 필요도 없기 때문에 바꿀 것 없음!
              this.speed += 10;
             if(this.speed>this.maxSpeed) {
                    this.speed=this.maxSpeed;
                     System.out.println("과속!");
              }
       }
       void speedUp(int speed) {
              // 기본형 -> 기능 구현 -> input, output이 올바른지 체크
              this.speed += speed; // 멤버변수 파란색, 통상변수 갈색
              if(this.speed>this.maxSpeed) {
                     this.speed=this.maxSpeed;
                    System.out.println("과속!");
              }
       }
       void showInfo() {
              System.out.println(this.name + "님의 현재 차량 상태 : [" + this.speed + "/" + this.maxSpeed + "]");
       }
       // 생성자 오버로딩
       Car(String name){
              this.name = name;
              this.speed = 0;
              this.maxSpeed = 200;
       }
       Car(String name, int speed, int maxSpeed){
              this.name = name;
              this.speed = speed;
              this.maxSpeed = maxSpeed;
       }
}
public class Test01 {

       public static void main(String[] args) {
              // Car car1 = new Car(); // 기본(디폴트) 생성자
              // 멤버변수가 내가 원하는 값대로 초기화되지 않는다.
              // 그래서 다음과 같이 만들고 싶어짐
              Car car1 = new Car("홍길동", 0, 200);
              // -> 생성자를 사용하는 이유 : 멤버변수를 원하는 값으로 초기화 가능 + 강제
              Car car2 = new Car("아리");

              car1.speedUp(130);
              car2.speedUp(130);

              car1.showInfo();
              car2.showInfo();
       }
}


*강사님! 원래는 car.showInfo();해야하는 걸
 System.out.println(car1);을 했더니! 주소가 떠요!?
   ex ) [I@5aaa6dsf]
      => 스택과 힙을 알면 이해하기 쉽다!
  혹시.....
   - 스택 오버플로우(=StackOverflow)를 본 적있는가?(Exception에) - 재귀함수에서 봤었다!!
      >>  스택과 이라는 공간 두 개 존재
            - 스택(Stack)
               : 실행할 때 쓰는 공간
               : 스택 오버플로우는 스택 공간에 갑자기 많은 데이터가 들어와서 과부화 걸린 상태
 
            - 힙(heap) (like 배열)
               : 개발자 영역이라고도 불린다.
               : new 라는 것 쓰면 객체 생성
               : 객체를 생성한다는 것은? heap 영역을 쓴다는 것
               : 스택에 주소를 넘겨주어 필요할 때 오도록 한다.

 

---위를 위해 강사님께서 들어준 예시
package class01;

class A{
       int x;
       int y;
       void show() {
              System.out.println(x+" / "+y);
       }
}

public class Test02 {
   
       public static void main(String[] args) {
      
              A a1=new A();
              A a2=new A();
      
              a1.x=10;
              a1.y=20;
      
              a2.x=11;
              a2.y=12;
      
              int[] data=new int[3];
              System.out.println(data);
      
              a1.show();
              System.out.println(a1);  
       }
}


-----------------------------------
[오늘 수업]

클래스에서 생성자를 만들 때
  생성자 내부의 반복되는 것들을 줄이는 방법!!
     this.
  -> 내가 가진 속성을 불러오겠다!
  : this == 자기 자신 객체
  : this()
      -> 함수(괄호가 있으면 무조건 함수!)
      -> 자기자신() == 생성자
     => this() == 본인의 생성자
- 쓰는 방법
   1. 인자가 많은 생성자 놔두고
   2. 다른 생성자에서 1번의 생성자를 재사용


package class02;

class Point{
       int x;
       int y;
       void showInfo() {
              System.out.println("P(" + this.x + ", " + this.y + ")");
       }
       Point(){
              this(0, 0); // 본인 생성자( ex ) 정수 두 개인 생성자) 불러오기
              System.out.println("기본생성자");
       }
       Point(int x){
              this(x, x);
              System.out.println("인자가 1개인 생성자");
       }
       Point(int x, int y){
              this.x = x;
              this.y = y;
              System.out.println("인자가 2개인 생성자");
       }
}


public class Test03 {
       public static void main(String[] args) {
              Point p1 = new Point(10, 20);
              Point p2 = new Point();
              Point p3 = new Point(123);

              p1.showInfo();
              p2.showInfo();
              p3.showInfo();
       }
}


26번 실행
28번 실행 -> 17로 이동 : 인자가 2개인 생성자
29번 실행 -> 9 -> 10 -> 17 : 
                               -> 11 : 기본생성자
30번 실행 -> 13 -> 14 -> 17 : 
                                 -> 15 : 인자가 1개인 생성자


-----------Test01을 this()를 이용하여 재코딩

package class01;

class Car{
       String name; // 멤버변수, 속성, 필드, 어트리뷰트
       int speed;
       int maxSpeed;
       void speedUp() { // 멤버함수, 메서드
              // 1. 기본형
              // 2. 기능구현
              // 3. input, output이 올바른지 체크
              //  -> 값을 받을 필요도, 돌려줄 필요도 없기 때문에 바꿀 것 없음!
              this.speed += 10;
              if(this.speed>this.maxSpeed) {
                     this.speed=this.maxSpeed;
                     System.out.println("과속!");
              }
       }
       void speedUp(int speed) {
              // 기본형 -> 기능 구현 -> input, output이 올바른지 체크
              this.speed += speed; // 멤버변수 파란색, 통상변수 갈색
              if(this.speed>this.maxSpeed) {
                     this.speed=this.maxSpeed;
                     System.out.println("과속!");
              }
       }
       void showInfo() {
              System.out.println(this.name + "님의 현재 차량 상태 : [" + this.speed + "/" + this.maxSpeed + "]");
       }
       // 생성자 오버로딩
       Car(String name){
              // 1. 인자가 많은 생성자만 놔두고,
              // 2. 다른 생성자에서 1번의 생성자를 재사용
              this(name, 0, 120);
       }
       Car(String name, int speed, int maxSpeed){
              this.name = name;
              this.speed = speed;
              this.maxSpeed = maxSpeed;
       }
}

public class Test01 {

       public static void main(String[] args) {
              // Car car1 = new Car(); // 기본(디폴트) 생성자
              // 멤버변수가 내가 원하는 값대로 초기화되지 않는다.
              // 그래서 다음과 같이 만들고 싶어짐
              Car car1 = new Car("홍길동", 0, 200);
              // -> 생성자를 사용하는 이유 : 멤버변수를 원하는 값으로 초기화 가능 + 강제
              Car car2 = new Car("아리");

              car1.speedUp(130);
              car2.speedUp(130);

              car1.showInfo();
              car2.showInfo();

       }
}

------강사님 문제

package class01;

class A{
       int x;
       int y;
       void show() {
              System.out.println(x+" / "+y);
       }
       A(){
              this(1,2);
              System.out.println("111");
       }
       A(int x){
              this(x,3);
              System.out.println("222");
       }
       A(int x,int y){
              this.x=x;
              this.y=y;
              System.out.println("333");
       }
}

public class Test02 {
   
       public static void main(String[] args) {
                    
              A a1=new A(13);
              A a2=new A();
                 
              a1.show();
              a2.show();
       }
}


어떻게 출력되는가?
  333
  222
  333
  111
  13 / 3
  1 / 2

그림판


-----------강사님의 코딩문제
main(){
  Student stu1=new Student("홍길동");
  Student stu2=new Student("아리",20);
  Student stu3=new Student("티모",21,95);

  stu1.show();
  stu2.show();
  stu3.show();
}
-> Console
홍길동 학생부 저장완료!
아리 학생부 저장완료!
티모 학생부 저장완료!

홍길동: Lv.1   SCORE: 0
아리: Lv.20   SCORE: 0
티모: Lv.21   SCORE: 95

---가 나오도록 코딩해보기

package class02;

class Student{
       String name; // 이름
       int level; // 레벨
       int score; // 점수

       void show() { // 메서드 show() 작성 this.를 붙이지 않아도 되지만 가독성을 위해!
              System.out.println(this.name + " : Lv." + this.level + "  SCORE : " + this.score);
       }

       Student(String name){
              this(name, 1, 0); // 인자가 1개인 생성자
       }
       Student(String name, int level){
              this(name, level, 0); // 인자가 2개인 생성자
       }
       Student(String name, int level, int score){ // 인자가 3개인 생성자
              this.name = name;
              this.level = level;
              this.score = score;
              System.out.println(this.name + " 생성완료!"); 
              // name으로 써도 되지만 this.name으로 가독성 증가
       }
}

public class Test04 {
       public static void main(String[] args) {
              // 생성자 -> 멤버변수를 초기화하기 위해서
              Student stu1 = new Student("홍길동"); // 인자가 1개인 생성자
              Student stu2 = new Student("아리", 20); // 인자가 2개인 생성자
              Student stu3 = new Student("티모", 21, 95); // 인자가 3개인 생성자

              System.out.println();
              stu1.show();
              stu2.show();
              stu3.show();
       }       
}

----------------------


- 멤버변수의 종류
  1. instance(객체) 변수
      : 객체의 멤버변수는 객체마다 고유한 값을 가진다.
           >> 객체에 저장된다.
      : 객체끼리의 값을 공유하지 않는다!  
           
  2. class 변수 ( = 공유자원 이라고도 부른다.)
      : 객체끼리 값 "공유"한다는 것
          => a객체의 변화가 b객체에도 영향을 준다.
      : 클래스의 변수 앞에 static을 붙인다.
          => static으로 인해 객체와 무관하게 되어버렸다.
                >> 클래스에 저장된다.
          => 그 값으로 고정되어 버린다.
                >> a1의 y값도 마지막에 입력받은 a2의 y값으로 
                     고정되어 버린 y값을 받는다.
          

   >> 인스턴스 변수가 압도적으로 많이 쓰여서 멤버변수 == 인스턴스 변수 처럼 되어버린 것
         
   
[공유] 개념

    ex ) 같은 캐릭터인데 속성이나 들고있는 아이템이 다르다
         >> 속성과 아이템이 객체
         >> 같은 캐릭터의 기본 공격력, 체력, 방어력은 같다


package class02;

// 멤버변수 : instance(객체) 변수 / class(클래스) 변수
class A{
       // 인스턴스(객체) 변수 == num1, num2
       int num1; // 멤버변수 : 객체마다 고유한 값 >> 객체끼리 값을 공유하지 않는다.
       // 클래스 변수
       static int num2;
       void showInfo() {
              System.out.println("num1 = " + this.num1);
              System.out.println("num2 = " + this.num2);
       }
       A(int num1, int num2){
              this.num1 = num1;
              this.num2 = num2;
       }
}

public class Test05 {
       public static void main(String[] args) {

              A a1 = new A(1, 2);
              A a2 = new A(10, 20);

              a1.showInfo();
              a2.showInfo();
       }
}
 
     >> 출력
          num1 = 1 
          num2 = 20
          num1 = 10
          num2 = 20

만약 이렇게 되면??
package class02;

// 멤버변수 : instance(객체) 변수 / class(클래스) 변수
class A{
       // 인스턴스(객체) 변수 == num1, num2
       int num1; // 멤버변수 : 객체마다 고유한 값 >> 객체끼리 값을 공유하지 않는다.
       // 클래스 변수
       static int num2;
       void showInfo() {
              System.out.println("num1 = " + this.num1);
              System.out.println("num2 = " + this.num2);
       }
       A(int num1, int num2){
              this.num1 = num1;
              this.num2 = num2;
       }
}

public class Test05 {
       public static void main(String[] args) {

              A a1 = new A(1, 2);
              A a2 = new A(10, 20);

              a1.num1 += 100;
              a1.num2 = 2;

              a1.showInfo();
              a2.showInfo();
       }
}
     >> 출력
          num1 = 1 
          num2 = 2
          num1 = 10
          num2 = 2

--------------또다른 예시
package class02;

class Dog{ // 흔한 코드는 아니지만 보여주기 위해 작성
       String name;
       static String[] action = new String[5]; // 어떤 값이던 서로 공유
       static int index; // 배운 개수, 이 값도 서로 공유!

       void showInfo() {
              System.out.println(name + " 강아지");
              for(int i = 0; i < index; i++) {
                     System.out.println(action[i]);
              }
       }
}

public class Test06 {
       public static void main(String[] args) {

              Dog dog1 = new Dog();
             dog1.name = "요요";

              Dog dog2 = new Dog();
              dog2.name = "꼬미";

              dog1.action[dog1.index] = "기다려!";
              dog1.index++;

              dog2.action[dog2.index] = "앉아!";
              dog2.index++;

              dog1.showInfo();
              dog2.showInfo();
       }
}

---------------강사님 문제
class Card{

}

main(){
  // 홍길동씨는 최초에 20만원 보유
  Card card1=new Card("홍길동");
  Card card2=new Card("홍길동",20000);

  card1.use();      // 10000원 사용: 남은 금액 190000원
  card1.use(100000);    // 100000원 사용: 남은 금액 90000원
  card2.use(50000);     // 50000원 사용: 한도초과! 남은 금액 90000원
  card2.use();          // 10000원 사용: 남은 금액 80000원
  card1.use(90000);     // 90000원 사용: 잔액부족! 남은 금액 80000원

  card1.showInfo(); // 홍길동님[남은금액: 80000원]
  card2.showInfo(); // 홍길동님[남은금액: 80000원]
}

-------내 답안
package class02;

class Card{
       String name;
       static int account;  // 초기화는 가능하나 이렇게 쓰면 클래스 변수처럼 보임
       int maxPay;

       void showInfo() { // 이름, 잔액 금액 출력
              System.out.println(this.name + "님[남은금액 : " + this.account + "]");
        }
       Card(String name){ // 카드 이름 하나만 입력받은 경우
              this(name, 200000); // this(name, maxPay) 받아오기
       }
       Card(String name, int maxPay){ // 카드 이름과 한도 두개 입력받은 경우
              this.name = name;
              this.maxPay = maxPay;
       }
       void use() { // 사용하는 금액 기본(디폴트) 메서드
              this.use(10000); // this에 use(pay)가져오기
       }
       void use(int pay){ // 사용하는 금액 메서드 use(pay)메서드 가져오기
              System.out.print(pay + "원 사용 : ");
              if(pay > this.maxPay) { // 한도보다 금액이 높을 경우
                     System.out.print("한도초과! ");
              }
              else if(pay > account){ // 계좌금액보다 금액이 높을 경우
                     System.out.print("잔액부족! ");
              }
              else { // 둘 다 해당이 안되면
                     account -= pay;
              }
              System.out.println("남은 금액 " + account);

              // 남은 금액을 출력하는 공통로직이 눈에 보이면 묶어주기 >> 모듈화
              // 모듈화 : 동일한 기능을 하나의 함수로 묶는 것
       }
}

public class Test07 {
       public static void main(String[] args) {
              // 홍길동씨는 최초에 20만원 보유
              Card card1 = new Card("홍길동");
              Card card2 = new Card("홍길동", 20000);

              Card.account = 200000;
              // 위처럼 사용하는 방법이 정확한 사용 방법이다.

              card1.use();        // 10000원 사용 : 남은 금액 190000원
              card1.use(100000);  // 100000원 사용 : 남은 금액 90000원
              card2.use(50000);   // 50000원 사용 : 한도초과! 남은 금액 90000원
              card2.use();        // 10000원 사용 : 남은 금액 80000원
              card1.use(90000);   // 90000원 사용 : 한도초과! 남은 금액 80000원 

              System.out.println();
              card1.showInfo();  // 홍길동님[남은 금액 : 80000원]
              card2.showInfo();  // 홍길동님[남은 금액 : 80000원]
       }
}

----강사님 풀이
static, 생성자 오버로딩, 메서드 오버로딩을 잘 이용할 수 있는지에 대한 것

package class04;

class Card{
       String name;
       int limit;
       static int bal;
       void use() {
      
              this.use(10000);
       }
       void use(int money) {
              System.out.print(money+"원 사용: ");
              if(money>this.limit) {
                     System.out.print("한도초과!");
              }
              else if(bal-money<0) {
                     System.out.print("잔액부족!");
              }      
              else {
                    bal-=money;
              }
              System.out.println(" 남은 금액 "+bal+"원");
       }
// 모듈화: 동일한 기능을 하나의 함수로 묶는 것
       void showInfo() {
              System.out.println(name+"님[남은금액: "+bal+"원]");
       }
       Card(String name){
              this(name,200000);
       }
       Card(String name,int limit){
              this.name=name;
              this.limit=limit;
       }
}
public class Test07 {

       public static void main(String[] args) {
              // 홍길동씨는 최초에 20만원 보유
              Card card1=new Card("홍길동");
              Card card2=new Card("홍길동",20000);
              card1.bal=200000;

              card1.use();      // 10000원 사용: 남은 금액 190000원
              card1.use(100000);    // 100000원 사용: 남은 금액 90000원
              card2.use(50000);     // 50000원 사용: 한도초과! 남은 금액 90000원
              card2.use();          // 10000원 사용: 남은 금액 80000원
              card1.use(90000);     // 90000원 사용: 잔액부족! 남은 금액 80000원

              card1.showInfo(); // 홍길동님[남은금액: 80000원]
              card2.showInfo(); // 홍길동님[남은금액: 80000원]
       }
}

 

System.out.println();
>> 클래스 변수다
System안에 out이라는 클래스변수다.
this.는 객체인데 static은 모두가 공유하는 것이라서
  this.account는 잘 사용하지 않는다.
   => 잘못된 것은 아니다.

 

this.use(10000)를 쓰게되는 상황
>> 예시로 설명
   ex ) 가위바위보(앱에서 종종 나온다)
       void 승부(가위){
           가위를 화면에 띄우는 작업
       }
       void 승부(바위){
           바위를 화면에 띄우는 작업
       }
       void 승부(보){
           보를 화면에 띄우는 작업
       }

 

-------------
모래성 게임 -- 강사님 작성
package class04;

import java.util.Random;

class Person{
       String name;
       static int sand=100;
       boolean game() {
              Random random = new Random();
              int num=random.nextInt(20)+1;
              System.out.println(name+"님이 "+num+" 가져갑니다..");
              sand-=num;
              System.out.println("남은 모래: "+sand);
              System.out.println();
              if(sand<=0) {
                     System.out.println(name+"님, 게임오버!");
                     return true;
              }
              return false;
       }
       Person(String name){
              this.name=name;
       }
}

public class Test08 {

       public static void main(String[] args) {
   
              Person p1=new Person("홍길동");
              Person p2=new Person("아리");
              Person p3=new Person("티모");
      
              while(true) {
                     if(p1.game()) {
                            break;
                     }
                     if(p2.game()) {
                            break;
                     }
                     if(p3.game()) {
                            break;
                     }
              }
     
       }
}

배열을 이용한 방법
package class04;

import java.util.Random;

class Person {
       String name;
       static int sand = 100; // 공유 자원 sand 클래스변수!
       boolean game() { // 메인쪽에서 승패를 받아야하기 때문에 return boolean
              Random random = new Random();
              int num = random.nextInt(20) + 1;
              System.out.println(name + "님이" + num + " 가져갑니다..");
              sand -= num;
              System.out.println("남은 모래 : " + sand);
              if(sand <= 0) {
                     System.out.println(name + "님 ,게임오버!");
                     return true;
              }
              return false;
       }
       Person(String name){
              this.name = name;
       }
}

public class Test08 {
       public static void main(String[] args) {
              // 배열이 필요하다
              // 1. 자료형이 같아야 한다
              // 2. 관련된 데이터여야 한다
              // 3. 개수가 같아야 한다
              // 객체 배열이 필요한 순간이다.
              Person[] p = new Person[3];
              p[0] = new Person("홍길동");
              p[1] = new Person("아리");
              p[2] = new Person("티모");

              int i = 0;
              while(true) { 
                     if(p[i].game()) { // for문을 표현
                            break;
                     }
                     i++;
                     if(i==p.length) {
                            i=0;
                     }
              }
       }
}

 

-------------------


ex ) 
5 : 5
6 : 6
1시간짜리 문제(복습할 문제)
-강사님이 준비한 문제
학생부프로그램

학생 3명까지밖에 못들어옴
3명, 학생 -> 배열 사용하면 된다
   비즈니스 메서드
   CRUD
   핵심 로직(메서드)
1. 추가 C
2. 출력 R
3. 정보 변경 U
(4. 삭제 D // 원래 있어야하는데 로직이 어려워 생략)
5. 종료


package class04;

import java.util.Scanner;

class Student{
       String name;
       int score;
       void showInfo() {
              System.out.println(name + "학생은 " + score + "점입니다.");
              System.out.println();
       }
       Student(String name, int score){
              this.name = name;
              this.score = score;
              System.out.println(this.name + "학생 입력완료!");
              System.out.println();
       }
}

public class Test09 {
       public static void main(String[] args) {

              Student[] data = new Student[3];
              int index = 0; // 저장

              Scanner sc = new Scanner(System.in) ;
              while(true) {
                      System.out.println("1. 추가");
                      System.out.println("2. 출력");
                      System.out.println("3. 변경");
                      System.out.println("4. 종료");
                     System.out.print("입력 > ");
                     int act = sc.nextInt();
                      // 사용자가 입력하면 -> 유효성 검사!
 
                     if(act == 1) { // 추가 => 유효성 검사 + 인덱스 체크
                             if(index == data.length) {
                                    System.out.println("데이터공간이 부족합니다.");
                                    continue;
                            }
                            System.out.print("학생 이름 입력 : ");
                            String name = sc.next();
                            System.out.print("학생 성적 입력 : "); // 0부터 100까지
                            int score = sc.nextInt();
 
                            data[index] = new Student(name, score); // 객체를 만들기만 하고 초기화는 안했다.
                            index++;
 
                      }
                      else if(act == 2) { // 출력
                             if(index == 0) { // 인덱스가 0 하나도 안 차 있으면
                                   System.out.println("저장한 정보가 없습니다");
                                   continue;
                             }
                             System.out.println("===학생 목록===");
                                    for(int i = 0; i < index; i++) {
                                   data[i].showInfo();
                           }
                     }
                     else if(act == 3) { // 변경
                            System.out.print("정보를 변경할 학생의 번호 입력 : ");
                            int num = sc.nextInt();
                           num--; // 번호와 인덱스 넘버의 차이
                            if(num < 0 || index <= num) {
                                   System.out.println("없는 번호입니다! 확인 후 다시 이용해주세요~~");
                                   System.out.println();
                                   continue;
                             }
                            System.out.print("변경할 점수 입력 : ");
                            data[num].score=sc.nextInt();
                            System.out.println(data[num].name + "학생 변경완료");
                            System.out.println();
                    }
                     else if(act == 4) { // 종료
                            System.out.println("종료됩니다...");
                            break;
                     }
                     else { // 이외의 숫자를 입력 시
                            System.out.println("잘못된 입력입니다.");
                     }
              }
       }
}