열아홉 번째 수업

정혅·2024년 3월 6일

더 조은 아카데미

목록 보기
24/76

오전 시험

  1. 배열을 이용해 성적 총합과 평균 구하기
package com.test.memo;


class Practice2 {
    public static void main(String[] args) {
        int[][] score = {
                {100, 100, 100},
                {20, 20, 20},
                {30, 30, 30},
                {40, 40, 40},
                {50, 50, 50}
        };
        result(score);
    }

    private static void result(int[][] score) {
        int num1 = 0, num2 = 0, num3 = 0;
        int[][] resultScore = new int[score.length][score[0].length + 3];
        for (int i = 0; i < score.length; i++) {
            for (int j = 0; j < score[i].length; j++) {
                resultScore[i][0] = i + 1;// 번호
                resultScore[i][j + 1] = score[i][j];// 과목
                resultScore[i][score[0].length + 1] += score[i][j];// 가로 총점구하기
                resultScore[i][score.length] = resultScore[i][score[0].length + 1] / score[i].length;

            }
            num1 += resultScore[i][1];
            num2 += resultScore[i][2];
            num3 += resultScore[i][3];
        }
        printScore(resultScore, num1, num2, num3);
    }

    private static void printScore(int[][] resultScore, int num1, int num2, int num3) {

        System.out.printf("번호\t국어\t영어\t수학\t총점\t평균\n");
        System.out.println("=============================================");

        for (int i = 0; i < resultScore.length; i++) {
            for (int j = 0; j < resultScore[i].length - 1; j++) {
                System.out.print(resultScore[i][j] + "\t");
            }
            System.out.print(Math.ceil(resultScore[i][resultScore[i].length - 1]) + "\n");
        }
        System.out.println("==============================================");
        System.out.printf("총점:\t%d\t%d\t%d", num1, num2, num3);
    }

}
  • 어제와는 다르게 다른 메서드로 분류해서 메인메서드에서는 호출만하면 자동 실행되게끔 작성했다.

  • 한번 했어서 큰 어려움은 없었다.


  1. 사용자로부터 숫자 2개를 입력받아서 해당 좌표가 1이면 O 아니면 X를 출력하게 프로그램을 짜시오
package com.test.memo;

import java.util.Scanner;

public class Practice3 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		while (true) {
			System.out.print("좌표를 입력하세요.(종료는00): ");
			String user = sc.next();
			boolean result = oneZero(user);
			if (!result) {
				System.out.println("종료합니다.");
				break;
			} else {
				continue;
			}
		}
		sc.close();
	}

	private static boolean oneZero(String user) {
		final int SIZE = 10;
		int x = 0, y = 0;
		String userInput = null;

		char[][] userBoard = new char[SIZE][SIZE];
		byte[][] shipBoard = {
				//  1  2  3  4  5  6  7  8  9
				{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1
				{ 1, 1, 1, 1, 0, 0, 1, 0, 0 }, // 2
				{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 3
				{ 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 4
				{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 5
				{ 1, 1, 0, 1, 0, 0, 0, 0, 0 }, // 6
				{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 7
				{ 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // 8
				{ 0, 0, 0, 0, 0, 1, 1, 1, 0 }, // 9
		};
		for (int i = 0; i < SIZE; i++) {// 사용자 배열에 사용자에게 보여질 숫자 패드 입력
			userBoard[0][i] = userBoard[i][0] = (char) (i + '0');
		}
		while (true) {
			if (user.length() == 2) {
				x = user.charAt(0) - '0';
				y = user.charAt(1) - '0';
			}
			if (user.contains("00")) {
				return false;
			}
			if (user.length() != 2 || x <= 0 || y <= 0 || x >= SIZE || y >= SIZE) {
				System.out.println("잘못된 입력입니다. 다시 입력해주세요");
				return true;
			}
			userBoard[x][y] = shipBoard[x - 1][y - 1] == 1 ? 'O' : 'X';

			for (int i = 0; i < userBoard.length; i++) {
				System.out.println(userBoard[i]);
			}
			System.out.println();
			return true;
		}
	}
}
  • 다른 메서드나 클래스로 나눠서 해보려했는데 사용자 값을 어떻게 가지고 와야할지 고민이 됐다 스터디시간에 할 예정
  • 사용자가 값을 잘못 입력했을 때나, 다시 좌표를 입력하라고 뜰때 while문과 다른 메소드에서 출력하고 다시 또 좌표를 입력하라고 출력하는 그 관계를 어떻게 코드를 짜야할지 조금 헷갈렸다.
  • 처음에는 무한루프가 돌아갔었고, 두번째는 종료 00 을 잘못된 입력이라고 알아들었었다 > else if문으로 해놔서 당연한거였는데 내눈에 안보였다..퐈하..

  1. 2차원 배열에 1~25를 넣고 셔플한 후 사용자에게 숫자를 받으면 해당 숫자를 0으로 바꿔 출력한다.
package com.test.memo;

import java.util.Scanner;

class Organize {
    public static void main(String[] args) {
        int user = 0, idx = 1, x = 0, y = 0;

        int[][] arr = new int[5][5];
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                arr[i][j] = idx++;// 1부터 차례대로 커지고 대입되게끔
            }
        }
        for (int i = 0; i < arr.length; i++) {// 차례로 대입시킨 배열 섞기
            for (int j = 0; j < arr[i].length; j++) {
                x = (int) (Math.random() * 5);
                y = (int) (Math.random() * 5);

                int temp = arr[i][j];
                arr[i][j] = arr[x][y];
                arr[x][y] = temp;
            }
        }
        do {

            for (int i = 0; i < arr.length; i++) {// 사용자에게 현재 배열 보여주는
                for (int j = 0; j < arr[i].length; j++) {
                    System.out.printf("%02d ", arr[i][j]);// 2자리수로 제한하고 공백은 0으로 채워준다.
                }
                System.out.println();
            }
            Scanner sc = new Scanner(System.in);
            System.out.print("1~25의 숫자를 입력하세요.(종료 0) : ");
            user = sc.nextInt();
            if (user > 25) {
                System.out.println("잘못된 입력입니다. 다시 입력하세요.\n");
            }
            outer: for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    if (arr[i][j] == user) {
                        arr[i][j] = 0;
                        break outer;
                    }
                }
            }
        } while (user != 0);
    }
}
  • 잘못됐다고 알려주는 기능도 넣었다

- class AAA{} class BBB{}가 상속받으려면
  • extends 키워드를 사용해 상속 받는다.
- 하위 클래스의 생성자에서 가장 먼저 해줘야 하는 일은?
  • super 키워드를 사용해 상위 클래스의 생성자를 호출해야한다.
- 메소드 오버라이딩에 대해서 설명하시오
  • 상위 클래스에서 상속받은 메소드를 하위클래스에서 재정의하는것으로, 메소드명, 리턴타입, 매개변수 타입과 개수가 동일해야한다.
- 모든 클래스의 최상위 클래스는?
  • Object클래스가 최상위 클래스이다.
- 클래스의 상속관계를 유지하면서, 메소드만 변경시켜 동일하게 출력시켜 보자
class Box {
    public void simpleWrap() {
        System.out.println("simple wrap");
    }
}

class PaperBox extends Box {
    public void paperWrap() {
        System.out.println("paper wrap");
    }
}

class GoldPaperBox extends PaperBox {
    public void goldWrap() {
        System.out.println("gold wrap");
    }
}

class InstanceOf {
    public static void wrapBox(Box box) {
        if (box instanceof GoldPaperBox)
            ((GoldPaperBox) box).goldWrap();
        else if (box instanceof PaperBox)
            ((PaperBox) box).paperWrap();
        else
            box.simpleWrap();
    }

    public static void main(String[] args) {
        Box box1 = new Box();
        PaperBox box2 = new PaperBox();
        GoldPaperBox box3 = new GoldPaperBox();

        wrapBox(box1);
        wrapBox(box2);
        wrapBox(box3);
    }
}

변경 전 코드

package com.test.memo;

class Box {
    public void Wrap() {
        System.out.println("simple wrap");
    }
}

class PaperBox extends Box {
    public void Wrap() {
        System.out.println("paper wrap");
    }
}

class GoldPaperBox extends PaperBox {
    public void Wrap() {
        System.out.println("gold wrap");
    }
}

class Organize {

    public static void wrapBox(Box box) {//제일 부모클래스가 현재 Box클래스니까 box로 통일해서 인자를 받는다.

        box.Wrap();
    }

    public static void main(String[] args) {
        Box box1 = new Box();
        PaperBox box2 = new PaperBox();
        GoldPaperBox box3 = new GoldPaperBox();

        wrapBox(box1);
        wrapBox(box2);
        wrapBox(box3);
    }
}
  • 객체를 생성할 때 각 객체의 타입은 다르지만, 이들이 서로 상속 관계에 있을 경우, 메소드 호출 시 동적 디스패치가 발생한다.

    • 동적 디스패치: 메소드 호출 시 실제 객체의 타입을 기반으로 해당하는 메소드를 찾아내어 실행하는 메커니즘이다.
  • WrapBox 메소드는 Box 클래스의 참조변수를 매개변수고 받고 있지만, 이 메소드를 호출할 때 전달되는 객체의 실제 타입에 따라 해당 객체의 오버라이드된 wrap메소드가 동적으로 선택되어 실행된다.


전날에 했던 상속 개념 복습

상속(Inheritance)

객체의 재사용 / 코드의 간결성 제공

  • extends라는 키워드를 통해 상속

    • 상속받고자 하는 자식 클래스 이름 뒤에 extends 키워드를 붙이고 부모 클래스 이름을 적어준다.

    • 자바는 다중 상속X > 단일 상속만 가능하다. > extends 키워드 뒤에 하나의 부모 클래스만 올 수 있다.

      • 여러 자식 클래스에게 상속은 가능
    • 자식 클래스는 부모 클래스로부터 메소드와 필드를 물려받아 사용 / 부모 클래스는 자식 클래에서 정의한 메소드나 필드를 사용하지 x (자식 = 자신 + 부모 / 부모 = 자신)

주의사항
  • Phone > 상위(super) 클래스

  • SmartPhone - 하위(sub) 클래스

class SmartPhone extends Phone{ }

Main(String[] args){

SmartPhone sp = nnew SmartPhone;

// SmartPhone 클래스 객체(sp) 생성

}
  • sp 라는 객체를 생성시, 하나의 객체(메모리)만 생성된다.

    • SmartPhone클래스가 Phone클래스에서 상속을 받는다고 해서 클래스 각각의 객체(메모리)를 만들어주는 것이 아니라, 한 객체에서 두 클래스가 같이 공존하는 구조이다.

상속(Inheritance) 과 접근 제한자

[public / protected / default / private]

private > default > protected > public 순으로 공유 범위가 넓어짐

메소드 오버라이딩

오버라이딩[메소드 재정의] > 서로 상속관계로 이루어진 객체들 간의 관계에서 비롯

메소드 오버라이딩은 반드시 상속 관계를 가진 클래스에서 등장한다.

  • super 클래스가 가지는 메소드를 sub클래스에서 똑같은 메소드로 만들게되면 더 이상 super 클래스의 이름이 같은 메소드를 호출할 수 없게 된다. > Overriding > 멤버 은폐


super / super()

1. super
  • 앞서 배운 this와 함께 객체를 참조할 수 있는 reference 변수

    • this는 특정 객체 내에서 자기 자신의 객체를 참조할 수 있는 유일한 reference 변수
  • super라는 reference 변수는 현재 객체의 바로 상위인 super 클래스(상위 클래스)를 참조할 수 있다.

2. super()
  • super 클래스의 생성자를 의미한다.

    • 인자가 존재한다면 인자의 형태와 일치하는 생성자를 의미
  • 객체(메모리 공간)가 생성될 때는, 본인 클래스의 기본 생성자가 호출(저장)되고, 부모의 객체의 생성자도 호출(저장)된다. 그 후에는 멤버 변수와 멤버 메서드가 저장 > 그 객체 자체를 가리키는 주소가 참조 변수

  • 부모 클래스가 선언한 기본 생성자에 인자 값이 있는 경우

    • 상속받는 자식 클래스에서 부모 클래스의 기본 생성자에 인자 값을 넣어 선언해야한다.

      • super(인자값);

[부모 클래스 생성자에 인자가 없는 경우]

  • 자식 클래스 내 부모 클래스명() 선언 > 생략

[부모 클래스 생성자에 인자가 있는 경우]

  • 자식 클래스 내 부모 클래스명(인자) 선

참조 자료형 형변환 및 다형성

상속 관계에 있는 객체의 자료형은 자식 클래스의 클래스명을 참조 자료형으로 사용하는데 부모 클래스의 자료형으로 변경할 수 있다. 이것을 참조 자료형 형 변환이라고 한다. 객체가 생성된 후 부모 클래스의 자료형을 사용하면 호출할 수 있는 범위가 부모 클래스의 멤버 변수, 멤버 메서드로 한정된다.

참조 자료형 형 변환을 통해 다형성(Polymorphism)을 구현할 수 있다. 다형성은 한 객체가 여러 모습을 가질 수 있다는 것을 의미한다. 다형성을 자바 언어 측면에서 살펴보면 한 객체가 여러 타입이 될 수 있다는 것을 의미한다.

업캐스팅(자동 형변환)

자식 클래스 -> 부모 클래스 타입 형 변환, 계층 구조 내 하위 클래스에서 상위 클래스로 단계가 높아짐.

참조 자료형의 수준을 높이기 때문에 자식 클래스의 참조 변수명만 기입.

다운 캐스팅(강제 형변환)

부모 클래스 -> 자식 클래스 타입 형 변환, 계층 구조 내 상위 클래스에서 하위 클래스로 단계가 낮아짐.

일부러 참조 자료형의 수준을 낮추기 때문에 부모 클래스의 참조 변수명 앞에 자식 클래스의 (참조 자료형)을 캐스팅해야 함.

주의 및 참고사항

한 객체의 참조 자료형의 형 변환이 일어나도, 객체의 메모리에 저장되어 있는 멤버 변수와 메서드 등... 데이터에 대한 손실 및 추가사항은 없다. 다만 호출할 수 있는 범위가 변동될 뿐이다.

**Point**
  • 업캐스팅 할 경우, 참조 자료형은 부모 클래스이므로, 호출 범위가 줄어들기에 자식 클래스 내 멤버 변수와 멤버 메서드는 호출하지 못한다.

  • 하지만 메서드 재정의(Overriding) 한 경우에는, 자식 클래스 내에 있는 멤버 변수나 멤버 메서드를 호출 가능.


final클래스 / final 메소드

변수에 final을 적용하면 상수지만, 메소드나 클래스 등에 붙으면 수정될 수 없음을 의미한다.

클래스, 필드, 메소드 선언시 사용

  • final 키워드가 메소드에 붙게 되면, 오버라이딩 할 수 없다.
  • final 키워드가 클래스에 붙게 되면, 더 이상의 상속 확장은 불가능하다.

추상 클래스 / 추상 메소드

1. 추상 클래스(abstract)

구체적인 개념으로부터 공통된 부분들만 추려내어 일반화할 수 있도록 하는것을 의미

일반적으로 사용할 수 있는 단계가 아닌 아직 미완성적 개념인 것

  • 일반 클래스와 달리 미완성되어있는 클래스로

    • 객체 생성이 불가능하다.

    • 상속관계를 맺은 자식 클래스가 객체로 생성되어야 사용이 가능하다.

      • 거의 쓰이지 않음

  • 추상 클래스가 단 한개라도 존재한다면, 그 클래스는 추상 클래스로 선언(abstract) > 문법

  • 추상 메소드도 상속이 가능 > 그럼 추상 메소드를 가지게 되는거니까 해당 상속 클래스도 추상 클래스를 시켜야한다.

    • 하지만 만약 오버라이딩해서 하위 클래스가 몸통이 있는 메소드로 사용한다면 추상 시킬 필요 없다. > 몸통이 있는 메소드는 내용을 안에 정의한 메소드
abstract class AAA(){} > 추상 클래스로 객체 생성 x

abstract class Hi{
    public abstract void hi() > 추상 메소드가 하나라도 존재한다면 해당 클래스는 추상 클래스로 선언
}

class BBB extends AAA{
    public void hi(){

    System.out.println("hi");
    }
}
  • 보통 Hi 클래스의 hi 추상 메소드라면 상속받는 하위클래스에게 몸통있는 메소드로 만들라는 의미이다. > 몸통있는 메소드 = 메소드속 내용이 있는는

  • public으로 상위 클래스에게 접근제어지시자로 받았으니까 무조건 public으로 접근제어지시자를 줘야한다.

2. 추상 메소드
  • 추상 클래스는 일반적으로 한 개 이상의 추상 메소드를 갖는다.

  • 추상 메소드는 일반 메소드와 다르게 메소드가 수행할 코드를 가지고 있지 x

    • 추상 메소드는 상속 시 자식 클래스에 반드시 구현되어야 자식 클래스가 객체 생성될 수 O

주의 및 참고사항
  • 추상 메소드는 {} 중괄호 블록X
3. 추상 클래스의 상속 관계
  • 추상 클래스들 간에도 상속이 가능하다. 일반 클래스들 간의 상속과 유사하지만 추상 클래스들 간의 상속에서는 상속받은 추상 메소드들은 꼭 재정의할 필요 없다.

    • 그냥 방학숙제 미루다가 마지막에 몰빵하듯이 나중에 재정의해도 되기 때

인터페이스(Interface)

클래스들이 필수로 구현해야 하는 추상 자료형 > 객체의 사용 방법을 가이드라인 하는 것

자바의 인터페이스는 추상 메소드와 상수로만 이뤄져있다 > 구현된 코드가 없기때문에 당연히 인터페이스로 인스턴스도 사용 x

인터페이스 특징
1. 다중 상속 가능
  • 인터페이스는 껍데기만 존재하여 클래스 상속 시 발생했던 모호함이 없다 > 다중 상속 가능
2. 추상 메소드와 상수만 사용 가능
  • 인터페이스에는 구현 소스를 생성할 수 x > 상수와 추상 메소드만 가질 수 O
3. 생성자 사용 불가
  • 인터페이스 객체가 아니므로 생성자 사용 x
4. 메소드 오버라이딩 필수
  • 자식 클래스는 부모 인터페이스의 추상 메소드를 모두 오버라이딩 해야한다.
인터페이스 사용 이유
  • 추상 클래스를 통해 객체들 간의 네이밍을 통일할 수 있고 이로 인해 소스의 가독성과 유지보수가 향상됩니다.
  • 확장에는 열려있고 변경에는 닫혀있는 객체 간 결합도(코드 종속성)를 낮춘 유연한 방식의 개발이 가능합니다.

자바 인터페이스 사용법 - interface
  • interface라는 키워드를 붙여서 만든다.

    • 단, interface라는 키워드를 붙여 인터페이스로 만들면implements라는 키워드를 통해 객체들을 구현하는 용도로만 가능하다.
    package Example;
    
    public interface Animal {
        public static final String name = "동물";
        
        public abstract void move();
        public abstract void eat();
        public abstract void bark();
    }
    
  • 인터페이스에는 static, final로 생성할 수 있는 상수와 abstract로 생성할 수 있는 추상 메서드만 가질 수 있다.

인터페이스끼리의 상속


자주 사용하는 자바 기본 클래스

String / StringBuffer / Math / Random / Date / Calendar 등... 강사님께서 자바에서 기본적으로 제공하는 일부의 클래스에 대한 내용과 메서드는 암기하라고 하셨다.

자바 API 문서 반드시 참고

1. String API

  • 패키지 : java.lang.String

  • final class

  • 문자열 가공할 때 사용.

  • String으로 객체를 만드는 방법은 두 가지가 있다.

    • String str1 = "abc"; // 암시적 객체 생성

    • String str1 = new String("abc"); // 명시적

명시적인 객체 생성 방법이 정석이지만, String 참조 자료형으로 객체를 만드는 경우는 매우 많아 간단하게 하고자 암시적 객체 생성 방법을 자주 사용함.

객체들 간의 비교는 '==(비교 연산자)' 사용

객체 내 문자열 간의 비교는 .equals() 메서드 사용

equals() 메서드

객체 내 문자열 간의 동일 여부를 판단하기 위해 사용. (대소문자 구별함)

반환값 - boolean

인자 - Object

equalsIgnoreCase() 메서드

객체 내 문자열 간의 동일 여부를 판단하기 위해 사용. (대소문자 구별 안 함)

반환값 - boolean

인자 - String


indexOf() 메서드

문자열 내 특정 문자가 가장 먼저 등장하는 위치(인덱스) 값을 찾는 메서드.

반환값 - int

인자 - String (한 글자인 경우 '' 문자로 표기 가능)

lastindexOf() 메서드

문자열 내 특정 문자가 가장 마지막에 등장하는 위치(인덱스) 값을 찾는 메서드.

반환값 - int

인자 - String (한 글자인 경우 '' 문자로 표기 가능)

charAt() 메서드

문자열 내 위치(인덱스) 값을 입력하면 해당 위치(인덱스) 값에 있는 문자를 찾는 메서드.

반환값 - char

인자 - int

substring() 메서드

문자열 내 위치(인덱스) 값을 입력하면 해당 위치(인덱스) 값의 문자부터 마지막 위치(인덱스) 값의 문자까지 모든 문자열을 추출하는 메서드.

반환값 - String

인자 - int(1개) / int(2개)

length() 메서드

문자열의 길이를 구하는 메서드.

반환값 - int

split() 메서드

문자열 내 특정 문자를 기준점으로 두고 문자열을 나눠서 배열 요소에 담는 메서드.

반환값 - String[]

인자 - String

toUpperCase() 메서드

문자열 내 소문자를 대문자로 변경할 때 사용.

반환값 - String

인자 - API를 보니 인자 값의 자료형은 나와있지 않은데, 문자(char)는 오류 문자열(String)만 받음... 확인!

toLowerCase() 메서드

문자열 내 대문자를 소문자로 변경할 때 사용.

반환값 - String

인자 - API를 보니 인자 값의 자료형은 나와있지 않은데, 문자(char)는 오류 문자열(String)만 받음... 확인!

replace() 메서드

특정 문자열을 변경할 때 사용.

반환값 - String

인자 - String("변경 전","변경 후")

trim() 메서드

문자열 내 공백을 제거할 때 사용.

반환값 - String

contains() 메서드

문자열 내 인자에 전달된 문자열 존재 유무 확인.

반환값 - boolean

인자 - String

startsWith() 메서드

문자열 내 인자에 전달된 문자열로 시작하는지 확인.

반환값 - boolean

인자 - String

endsWith() 메서드

문자열 내 인자에 전달된 문자열로 끝나는지 확인.

반환값 - boolean

인자 - String

valueOf() 메서드

여러 자료형의 데이터를 String 참조 자료형으로 변환할 때 사용하는 메서드.

반환값 - statc String (static형이라 객체 생성 X)

인자 - 기본 자료형 모두

valueOf() 메서드는 static String으로 반환하므로, 메서드를 호출할 때도 생성한 객체를 통해 호출할 수 없다.

'String.valueOf(인자 값);' 메서드 앞에 클래스명을 작성해야 한다.

기본 자료형은 기본 자료형끼리 (예 - 정수와 실수를 계산하기 위해 정수가 실수화되는 경우)

참조 자료형은 참조 자료형끼리 (예 - 상속 관계를 가진 클래스의 다형성을 이용한 객체 생성)

같은 자료형으로 데이터 타입을 변경하는 걸 형 변환 (casting)이라고 한다.

int형 데이터 타입 -> String형 데이터 타입

(예 - String.valueOf(인자 값);)

String형 데이터 타입 -> int형 데이터 타입

(예 - Integer.ParseInt(인자 값);)

기본 자료형과 참조 자료형, 다른 자료형으로 데이터 타입을 변경하는 걸 변환(parsing)이라고 한다.

2. StringBuffer

  • 패키지 : java.lang.StringBuffer

  • final class

  • 문자열 가공할 때 사용.

String(참조 자료형)은 '문자열 불변의 법칙'이라는 특성을 가지고 있어 문자열을 가공(추가/수정) 할 때마다 객체를 항상 생성해야 하며, 이로 인해 쓰레기 객체가 발생하여 메모리를 효율적이게 관리하지 못한다.

자바에서는 이렇게 발생한 쓰레기 객체를 사용하지 않고, 일정 시간이 지난 후에는 삭제하며 메모리를 효율적이게 관리할 수 있도록 StringBuffer 사용을 권장한다.

insert() 메서드

원하는 위치(인덱스 값)에 데이터 추가하는 메서드

인자 - 위치(인덱스 값), 추가할 데이터

append() 메서드

기존 문자열 바로 뒤에 문자열 추가.

인자 - 추가할 데이터

replace() 메서드

특정 위치(인덱스 값)부터 특정 위치(인덱스 값-1)까지의 문자열을 지정한 문자열로 대체하여 변경.

인자 - 위치(인덱스 값), 위치(인덱스 값), 변경할 데이터

deleteCharAt() 메서드

특정 위치(인덱스 값)에 있는 데이터 삭제.

인자 - 위치(인덱스 값)

delete() 메서드

특정 위치(인덱스 값)부터 특정 위치(인덱스 값-1)까지의 문자열을 삭제.

인자 - 위치(인덱스 값), 위치(인덱스 값)

StringBuffer 클래스를 사용하면, String 클래스처럼 문자열이 바뀔 때마다 객체를 생성할 필요 없이 하나의 객체로 메서드문만 수행하여 문자열 가공이 가능.

문자열 가공(데이터 수정)이 완료되면, 최종 문자열을 StringBuffer 자료형에서 String 자료형으로 바꿔서 사용하면 된다.

3. Math

  • 패키지 : java.lang.Math

  • final class

  • 연산 및 수학적인 기능이 필요할 경우 사용

  • Math의 가장 큰 특징은, 모든 메서드가 static 형식이다. (객체 생성하여 사용 X - 클래스명 언급 필수)

abs() 메서드

절댓값을 구하는 메서드.

반환값 - double, float, int, long

인자 - double, float, int, long

ceil() 메서드

소수점 이하 '0'처리하고 올림 처리.

반환값 - double

인자 - double

floor() 메서드

소수점 이하 '0'처리하고 내림 처리.

반환값 - double

인자 - double

round() 메서드

실수 데이터를 반올림(소수점 버리기) 할 때 사용.

반환값 - (int) / [long]

인자 - (float) / [double]

max() 메서드

최댓값을 구하는 메서드.

반환값 - double, float, int, long (1개)

인자 - double, float, int, long (2개)

min() 메서드

최솟값을 구하는 메서드.

반환값 - double, float, int, long (1개)

인자 - double, float, int, long (2개)

random() 메서드

0.0~0.9999999999999999 난수 값 구하기.

반환값 - double


4. Date

  • 패키지 : java.util.Date

  • 일반 class

  • 날짜를 구할 때 사용하는 클래스.

toString() 메서드

현재 기준 날짜를 확인할 때 사용하는 메서드

- Tue Nov 09 22:18:25 KST 2021

- 형식이 우리나라에 맞지 않아서 별로 안 씀

반환값 - String

toLocaleString() 메서드

현재 기준 날짜를 확인할 때 사용하는 메서드

- 2021. 11. 9. 오후 10:18:25

- 자바 API에서 Deprecated 선언 (Deprecated : 자바에서 사용하지 말라고 권고한 시한부 메서드)

반환값 - String

5. DateFormat

  • 패키지 : java.text.DateFormat

  • 추상 클래스 (직접 객체 생성 불가 = new(X))

  • extends Format

  • 날짜를 구할 때 사용하는 클래스.

getInstance() 메서드

현재 기준 날짜를 확인할 때 사용하는 메서드

- 21. 11. 9. 오후 10:18

- 짧은 형식으로 가져옴.

반환값 - static DateFormat

getDateTimeInstance() 메서드

현재 기준 날짜를 확인할 때 사용하는 메서드

- 2021. 11. 9. 오후 10:41:38

- 우리나라 표준 형식에 가깝게 가져옴.

반환값 - static DateFormat

format() 메서드

생성한 날짜를 문자열로 형식화할 때 사용.

반환값 - String

6. SimpleDateFormat**

  • 패키지 : java.text.SimpleDateFormat

  • 일반 class

  • extends DateFormat

  • 객체를 생성할 때 생성자 인자 값에 날짜 형식 표(Date and Time Patterns)를 참고하여 데이터를 입력하여 날짜를 구할 때 사용하는 클래스.

format() 메서드

생성한 날짜를 문자열로 형식화할 때 사용.

반환값 - String

7. Calendar

  • 패키지 : java.util.Caledar

  • 추상 class

  • 필드 내 변수(년/월 등...)가 상수처리, 거의 대문자

  • 년/월/일/시/분/초 데이터를 따로 구하여 사용할 때에는 Date 클래스보다는 Calendar 클래스를 활용.

getInstance() 메서드

현재 기준 날짜를 확인할 때 사용하는 메서드

  • java.util.GregorianCalendar[time=163...

  • 시간에 이용되는 모든 데이터의 단위를 가져온다.

  • MONTH = 0~11 (컴퓨터에서는 0월~11월로 표기하기 때문에, 현실 시간을 불러오기 위해서라면 항상 MONTH 값에 +1을 해줘야 한다.)

반환값 - static Caledar

get() 메서드

getInstance() 메서드로 확인한 날짜 데이터(주어진 달력 필드의 값) 값을 반환할 때 사용하는 메서드.

반환값 - int


상속 실습문제

  1. Friend 클래스
    이름
    전화번호
    주소
    메소드
    showData : 모든 데이터(전체 제이터)를 출력하는 메소드
    showBasicInfo : 기본 데이터(일부 데이터)를 출력하는 메소드
    HighFriend 클래스 (Friend 클래스 상속)
    직장
    메소드
    showData : 모든 데이터(전체 제이터)를 출력하는 메소드
    showBasicInfo 메소드에서 이름, 전화번호, 직장을 출력
    UnivFriend 클래스 (Friend 클래스 상속)
    전공
    메소드
    showData : 모든 데이터(전체 제이터)를 출력하는 메소드 :이름 전번 주소 전공
    showBasicInfo 메소드에서 이름과 전공학과를 출력 : 이름 전공
    ** 메뉴 선택 **

    1. 고교 정보 저장
    2. 대학 친구 저장
    3. 전체 정보 출력
    4. 전체 기본 정보 출력
    5. 프로그램 종료
      선택>>
내가 푼 코드
package com.test.memo;

import java.util.Scanner;

class Friend {// 이름 번호 주소
    String name, num, address;

    Friend(String name, String num, String address) {
        this.name = name;
        this.num = num;
        this.address = address;
    }

    public void showData() {// 모든 데이터를 출력하는 메소드
        System.out.println("이름: " + name);
        System.out.println("전화번호: " + num);
        System.out.println("주소: " + address);
    }

    public void showBasicInfo() {// 기본 데이터를 출력하는 메소드
        System.out.println("이름: " + name);
        System.out.println("전화번호: " + num);
    }
}

class HighFriend extends Friend {// 직장
    String office;

    public HighFriend(String name, String num, String address, String office) {
        super(name, num, address);//상위 생성자 호출(가장 먼저 해야하는것!!)
        this.office = office;
    }

    public void showData() {// 모든 데이터 출력
        super.showData();//오버라이딩 
        System.out.println("직장: " + office);// 이름, 전화번호, 직장을 출력
    }

    public void showBasicInfo() {
        super.showBasicInfo();
        // System.out.println("직장: " + office);
    }
}

class UnivFrind extends Friend {// 전공
    String major;

    public UnivFrind(String name, String num, String address, String major) {
        super(name, num, address);
        this.major = major;
    }

    public void showData() {// 이름 번호 주소 전공 출력
        super.showData();
        System.out.println("전공: " + major);
    }

    public void showBasicInfo() {
        System.out.println("이)
        System.out.println("전공: " + major);
    }
}

class Organize {
    public static void main(String[] args) {
        boolean flag = true;
        int user = 0;
        String name = null, num = null, address = null, office = null, major = null;
        Scanner sc = new Scanner(System.in);
        Friend[] friends = new Friend[100];
        int friendCnt = 0;

        do {
            printUI();
            user = sc.nextInt();
            sc.nextLine();
            switch (user) {
            case 1:
                System.out.print("이름: ");
                name = sc.nextLine();
                System.out.print("전화번호: ");
                num = sc.nextLine();
                System.out.print("주소: ");
                address = sc.nextLine();
                System.out.print("직장: ");
                office = sc.nextLine();
                friends[friendCnt++] = new HighFriend(name, num, address, office);
                System.out.println("고교 친구 정보 저장");
                break;

            case 2:
                System.out.print("이름: ");
                name = sc.nextLine();
                System.out.print("전화번호: ");
                num = sc.nextLine();
                System.out.print("주소: ");
                address = sc.nextLine();
                System.out.print("전공: ");
                major = sc.nextLine();
                friends[friendCnt++] = new UnivFrind(name, num, address, major);
                System.out.println("대학 친구 정보 저장");
                break;

            case 3:
                System.out.println("*** 전체 정보 출력 ***");
                for (int i = 0; i < friendCnt; i++) {
                    friends[i].showData();
                }
                System.out.println("----------------------");
                break;

            case 4:
                System.out.println("*** 전체 기본 정보 출력 ***");
                for (int i = 0; i < friendCnt; i++) {
                    friends[i].showBasicInfo();
                }
                System.out.println("----------------------");
                break;

            case 5:
                System.out.println("프로그램을 종료합니다.");
                flag = false;
                break;
            }
        } while (flag);
        sc.close();
    }

    public static void printUI() {
        System.out.println();
        System.out.println("*** 메뉴 선택 ***");
        System.out.println("1. 고교 정보 저장");
        System.out.println("2. 대학 친구 저장");
        System.out.println("3. 전체 정보 출력");
        System.out.println("4. 전체 기본 정보 출력");
        System.out.println("5. 프로그램 종료");
        System.out.print("선택>>");
    }
}

제일 상위클래스의 생성자를 만들고, 각각의 하위 클래스의 생성자를 정의하다보니 대충 감이 왔다 > 공통기능을 하나를 상위로 두고 각각 다른 기능을 하위로 둬서 동작하게 하는구나! 느꼈다

  • 변수들을 private으로 뒀어야하는데 깜빡쓰..

  • 배열을 만들때 제일 상위에 있는 (=공통된 기능 클래스) 클래스로 배열을 만들어서 다른 기능을 하는 클래스들을 객체로 만드는 방법 잘 기억해두자..(넘 어렵쓰)

    • friends[0]에는 HighFriend 객체가, friends[1]에는 UnivFriend 객체가 들어가게 됩니다. friendCnt를 통해 현재 저장된 객체의 개수를 추적하고 있기 때문에, friendCnt의 값에 따라 다음에 저장될 객체의 위치가 결정됩니다. 처음에 HighFriend 객체를 저장하면서 friendCnt가 1이 되고, 그 다음에 UnivFriend 객체를 저장하면 friendCnt는 2가 되므로 각 객체는 friends[0]friends[1]에 저장됩니다.
  • case문에서 반복해서 사용자 값 받는거를 중복 계속 시키면 좋지 않다.. 중복되는 것들은 다 걷어내서 한번만 돌아가게끔..(유지보수 x)

선생님 코드 > 책
import java.util.Scanner;

class Friend 
{
    String name;
    String phoneNum;
    String addr;

    public Friend(String name, String phone, String addr)
    {
        this.name=name;
        this.phoneNum=phone;
        this.addr=addr;
    }
    public void showData()
    {
        System.out.println("이름 : "+name);
        System.out.println("전화 : "+phoneNum);
        System.out.println("주소 : "+addr);
    }
    public void showBasicInfo(){}//아무것도 적지 않았다고 삭제시키면 배열 자료형이 Friend이기 때문에 해당 클래스 메서드에는 BaiscInfo가 없어서 오류난다. 
                                 //자바가 바보같이 없다고 생각 실질적으로는 존재 > 형변환 필요 
                                 //일관적인 규칙성을 위해서는 필요한 메소드 
}

class HighFriend extends Friend        // 고교동창
{
    String work;

    public HighFriend(String name, String phone, String addr, String job)
    {
        super(name, phone, addr);
        work=job;        
    }
    public void showData()
    {
        super.showData();
        System.out.println("직업 : "+work);
    }
    public void showBasicInfo()
    {
        System.out.println("이름 : "+name);
        System.out.println("전화 : "+phoneNum);
    }
}

class UnivFriend extends Friend     // 대학동기
{
    String major;        // 전공학과
    public UnivFriend(String name, String phone, String addr, String major)
    {
        super(name, phone, addr);
        this.major=major;
    }
    public void showData()
    {
        super.showData();
        System.out.println("전공 : "+major);
    }
    public void showBasicInfo()
    {
        System.out.println("이름 : "+name);
        System.out.println("전화 : "+phoneNum);
        System.out.println("전공 : "+major);
    }
}

class FriendInfoHandler
{
    private Friend[] myFriends;
    private int numOfFriends;

    public FriendInfoHandler(int num)
    {
        myFriends=new Friend[num];
        numOfFriends=0;
    }

    private void addFriendInfo(Friend fren)
    {
        myFriends[numOfFriends++]=fren;
    }

    public void addFriend(int choice)
    {
        String name, phoneNum, addr, job, major;

        Scanner sc=new Scanner(System.in);        
        System.out.print("이름 : "); name=sc.nextLine();
        System.out.print("전화 : "); phoneNum=sc.nextLine();
        System.out.print("주소 : "); addr=sc.nextLine();

        if(choice==1)
        {
            System.out.print("직업 : "); job=sc.nextLine();
            addFriendInfo(new HighFriend(name, phoneNum, addr, job));
        }
        else    // if(choice==2)
        {
            System.out.print("학과 : "); major=sc.nextLine();
            addFriendInfo(new UnivFriend(name, phoneNum, addr, major));
        }
        System.out.println("입력 완료! \n");
    }

    public void showAllData()
    {
        for(int i=0; i<numOfFriends; i++)
        {
            myFriends[i].showData();
            System.out.println("");
        }
    }

    public void showAllSimpleData()
    {
        for(int i=0; i<numOfFriends; i++)
        {
            myFriends[i].showBasicInfo();//Firend클래스에서 BasicInfo()메소드 삭제하면 여기서 오류 

            System.out.println("");
        }
    }
}

class MyFriendInfoBook
{
    public static void main(String[] args)
    {
        FriendInfoHandler handler=new FriendInfoHandler(10);

        while(true)
        {            
            System.out.println("*** 메뉴 선택 ***");
            System.out.println("1. 고교 정보 저장");
            System.out.println("2. 대학 친구 저장");
            System.out.println("3. 전체 정보 출력");
            System.out.println("4. 기본 정보 출력");            
            System.out.println("5. 프로그램 종료");
            System.out.print("선택>> ");

            Scanner sc=new Scanner(System.in);
            int choice=sc.nextInt();

            switch(choice)
            {
            case 1: case 2:
                handler.addFriend(choice);
                break;
            case 3:
                handler.showAllData();
                break;
            case 4:
                handler.showAllSimpleData();
                break;
            case 5:
                System.out.println("프로그램을 종료합니다.");
                return;
            }
        }
    }
}
  • Scanner객체를 계속 클래스마다 생성하는건 좋지 않다.

  • Friend 클래스 : 어떤 클래스의 상위클래스로 사용하기 위해 만든 클래스이다. > 객체를 생성하며 안되는 클래스(문법적으로는 가능하나, ) 논리

  • Friend 클래스 앞에 absract 라고 키워드를 붙인다면 객체 생성할 수 없다.


어노테이션

소스코드에 추가해서 사용할 수 있는 메타 데이터의 일종

  • 메타 데이터: 애플리케이션이 처리해야할 데이터가 아닌, 컴파일 과정과 실행과정에서 코드를 어떻게 처리해야하는지 알려주기 위한 추가 정보

  • 보통'골뱅이(@)' 기호를 앞에 붙여 사용

    • jdk1.5버전 이상부터 사용 가능 > 클래스 파일에 임베디드되어 컴파일러에 의해 생성된 이후 JVM에 포함되어 동작
  1. 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보 제공

  2. 소프트웨어 개발 환경이 빌드나 배포시 코드를 자동으로 생성할 수 있도록 정보 제공

  3. 런타임에 특정 기능을 실행하도록 정보를 제공

자주 이용하는 어노테이션

@Override
  • 메소드를 오버라이드하겠다는 의미 > 메소드 선언 앞에 붙여준다.

    • 만약 상속받은 부모 클래스 , 구현해야 할 인터페이스에서 해당 메소드가 없다면 컴파일 오류 발생
@Override
public void getInfo() {
  System.out.println("test");
}
@Deprecated
  • 이 메소드를 사용하는 애플리케이션을 컴파일 할 경우 컴파일 경고 발생

    • 하위호환을 위해 메소드 자체를 없애지는 못하지만, 사용하지 말 것을 사용자에게 알리고싶을 때 붙여준다.
@SuppressWarnings(인자)
  • 컴파일러 경고를 출력하지 않도록 설정한다.

  • SuppressWarnings() 어노테이션은 인자를 받는데 인자에 따른 의미는 다음과 같다.

    • "all" : 모든 경고를 억제

    • "cast" : 타입 캐스트 관련 경고 억제

    • "dep-ann" : 사용하지 말아야할 주석 관련 경고 억제

    • "deprecation" : Dprecated 메소드를 사용한 경우 발생하는 경고 억제

    • "fallThrough" : switch문에서 break 구문 누락 관련 경고 억제

    • "finally" : finally 블럭 관력 경고 억제

  • 컴파일러 경고는 경고일 뿐, 경고 상황을 개발자가 알고 있는 경우에는 컴파일 로그가 지저분해지고 진짜 잡아야하는 경고들이 잘 보이지 않을 수 있기 때문에 어노테이션 사용


정수의 자리수 출력

숫자를 입력하세요.
314
314는 3자리 숫자 입니다. > int형 배열로 만들

내가 푼 코드
class Practice1{
    public static void main(String[] args) {
        int[] userArr = new int [10];
        int user = 0, cnt = 0;
        boolean flag = true;
        Scanner sc = new Scanner(System.in);

        while(flag) {
            System.out.print("숫자를 입력하세요(종료 00): ");
            user = sc.nextInt();
            for(int i = 0; i < cnt; i++) {
                String num = Integer.toString(userArr[i]);
                if(userArr[i] == 00) {
                    System.out.println("프로그램을 종료합니다.");
                    flag = false;
                    break;
                }
                System.out.println(num + "은 " + num.length() + "자리 숫자입니다.");
            }
        }
    }
}
  • 10자리를 벗어나면 오류메세지 출력하려하는데 아예 오류가 떠버려서.. 스터디때 해보자
선생님 코드1
public class Test3 {

    public static void main(String[] args) {
        int num = 123;
        int[] arr = new int[3];
        makeArr(arr, num);
    }

    public static void makeArr(int[] arr, int num) {
        int divisor = 1;
        for(int i=0;i<arr.length-1;i++)
            divisor *= 10;
        for(int i=0;i<arr.length;i++)
        {
            arr[i] = num / divisor;
            num %= divisor;
            divisor /= 10;
        }        
    }
}
선생님 코드 2
import java.util.Scanner;

public class Test4 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("숫자를 입력하세요.");
        int num = sc.nextInt();        
        int len = calNumOfDigits(num);
        int[] arr = new int[len];
        makeArr(arr, num);
    }
    public static int calNumOfDigits(int num) {
        int i = 0;
        for(i=0;num != 0;i++)
            num /= 10;
        return i;
    }
    public static void makeArr(int[] arr, int num) {
        int divisor = 1;
        for(int i=0;i<arr.length-1;i++)
            divisor *= 10;
        for(int i=0;i<arr.length;i++)
        {
            arr[i] = num / divisor;
            num %= divisor;
            divisor /= 10;
        }        
    }    
}

int[] num = {1, 3, 4, 5, 7, 10, 27, 39, 50, 92};
이진 검색으로 위에 1차원 배열에서
5를 검색해 보자.
9를 검색해 보자.
검색결과가 있다면 배열의 인덱스를 출력하고, 없으면 검색결과가 없다고 출력하자.
몇 번만에 검색되었는지 횟수도 출력하자.

내가 푼 코드 - 이진검색은 반드시 배열이 정렬되어 있어야 한다.
package com.test.memo;

import java.util.Scanner;

class Practice2 {
    public static void main(String[] args) {
        int[] num = { 1, 3, 4, 5, 7, 10, 27, 39, 50, 92 };

        Scanner sc = new Scanner(System.in);

        System.out.print("검색하고자 하는 숫자를 입력하세요: ");
        int user = sc.nextInt();// 5
        int result = binary(num, user);

        if (result != -1) {
            System.out.println("원소 " + user + "은(는) 인덱스 " + result + "에 위치해 있습니다.");
        } else {
            System.out.println("원소를 찾지 못했습니다.");
        }
    }

    private static int binary(int[] num, int user) {
        int cnt = 0, first = 0,end = num.length - 1;
        Arrays.sort(num);//오름차순 시켜놓
        while (first <= end) {
            cnt++;
            int mid = (first + end) / 2;

            if (user == num[mid]) {
                System.out.println(cnt + "번만에 찾았습니다.");
                return mid;

            } else if (user > num[mid]) {
                first = mid + 1;
            } else {
                end = mid - 1;
            }
        }
        return -1;
    }
}
  1. 처음에 중심을 어떻게 기준으로 새우는지 고민했는데, 그냥 인덱스의 길이를 /2 하면 됐던거였다.

  2. 다른 메소드로 만들 생각은 없었는데 챗 지피티의 도움으로 이렇게 만들었다.

  3. 미드를 와 사용자 입력값이 같으면 출력하는 것은 알았는데 그 후에 작거나 크면, 시작값이나 끝 값을 해당 기준값으로 시작하면 되는줄 알았는데 거기에 +1 하고 -1 을 해야하는것이였다.

    • user == num[mid]: 현재 중간 값이 찾는 값과 일치하면 찾았으므로 반환합니다.

    • user > num[mid]: 찾는 값이 중간 값보다 크다면, 찾는 값은 중간 값보다 오른쪽에 있을 가능성이 있습니다. 따라서 검색 범위를 현재 중간 값의 오른쪽으로 좁힙니다. (first = mid + 1)

    • user < num[mid]: 찾는 값이 중간 값보다 작다면, 찾는 값은 중간 값보다 왼쪽에 있을 가능성이 있습니다. 따라서 검색 범위를 현재 중간 값의 왼쪽으로 좁힙니다. (end = mid - 1)

      • 반복하여 검색 범위를 좁혀가다가 찾는 값과 일치하는 값을 찾거나 검색 범위가 더 이상 없을 때까지 진행

전화번호 관리 프로그램 4단계(상속)

내가 푼 코드
package com.test.memo;

import java.util.Scanner;

class PhoneInfo {
    private String name, phoneNumber, birth;

    PhoneInfo(String name, String phoneNumber, String birth) {
        this.name = name;
        this.phoneNumber = phoneNumber;
        this.birth = birth;
    }

    PhoneInfo(String name, String phoneNumber) {// birth 없이 출력 가능하게
        this.name = name;
        this.phoneNumber = phoneNumber;
    }

    public String getName() {
        return name;
    }

    public void showData() {// 전체 정보
        System.out.printf("이름: %s\n", name);
        System.out.printf("전화번호: %s\n", phoneNumber);
        System.out.printf("생년월일: %s\n", birth);
    }

    public void basicData() {// 기본정보
        System.out.printf("이름: %s\n", name);
        System.out.printf("전화번호: %s\n", phoneNumber);
    }
}

class PhoneUnivInfo extends PhoneInfo {// 대학 동기들의 전화번호 저장
    private String major; // 전공
    private int year; // 학년

    PhoneUnivInfo(String name, String phoneNumber, String major, int year) {
        super(name, phoneNumber);
        this.major = major;
        this.year = year;
    }

    public void showData() {
        super.showData();
        System.out.printf("전공: %s\n", major);
        System.out.printf("학년: %d\n", year);
    }

    public void basicData() {
        super.basicData();
        System.out.printf("전공: %s\n", major);
        System.out.printf("학년: %d\n", year);
    }
}

class PhoneCompanyInfo extends PhoneInfo {
    private String company;

    public PhoneCompanyInfo(String name, String phoneNumber, String company) {
        super(name, phoneNumber);
        this.company = company;
    }

    public void showData() {
        super.showData();
        System.out.printf("회사: %s\n", company);
    }

    public void basicData() {
        super.basicData();
        System.out.printf("회사: %s\n", company);
    }
}

class PhoneInfoHandler {
    private PhoneInfo phone[];
    private int phoneCnt;

    public PhoneInfoHandler(int num) {
        phone = new PhoneInfo[num];
        phoneCnt = 0;
    }

    public int getPhoneCnt() {
        return phoneCnt;
    }

    private void addPhoneInfo(PhoneInfo pp) {
        phone[phoneCnt++] = pp;
    }

    public void addPhone() {
        String name, phoneNum, major, company;
        int year;
        Scanner sc = new Scanner(System.in);

        System.out.println("데이터 입력을 시작합니다.");
        System.out.println("1.일반 2.대학 3.회사");
        System.out.print("선택: ");
        int user = sc.nextInt();
        sc.nextLine();// 버퍼에 엔터 빼주기

        System.out.print("이름: ");// 공통된 입력 질문들
        name = sc.nextLine();
        System.out.print("전화번호: ");
        phoneNum = sc.nextLine();

        if (user == 1) {
            addPhoneInfo(new PhoneInfo(name, phoneNum));
        } else if (user == 2) {
            System.out.print("전공: ");
            major = sc.nextLine();
            System.out.print("학년(숫자만): ");
            year = sc.nextInt();
            sc.nextLine();

            addPhoneInfo(new PhoneUnivInfo(name, phoneNum, major, year));
        } else {
            System.out.print("회사: ");
            company = sc.nextLine();
            addPhoneInfo(new PhoneCompanyInfo(name, phoneNum, company));
        }
        System.out.println("데이터 입력이 완료되었습니다.");
    }

    public void searchDataByName(String searchName) {
        boolean found = false;
        for (int i = 0; i < phoneCnt; i++) {
            if (phone[i].getName().equals(searchName)) {
                phone[i].basicData();
                found = true;
            }
        }
        if (!found) {
            System.out.println("해당 이름의 데이터를 찾을 수 없습니다.");
        }
    }

    public void deleteDataByName(String deleteName) {
        boolean found = false;

        for (int i = 0; i < phoneCnt; i++) {
            if (phone[i].getName().equals(deleteName)) {
                found = true;
                System.out.println(deleteName + "의 데이터를 삭제합니다.");

                for (int j = i; j < phoneCnt; j++) {// 삭제할 인덱스부터 존재하는 인덱스까지 한칸 씩 땡기기위해서
                    phone[j] = phone[j + 1];
                }
                phoneCnt--;
                break;
            }
        }
        if (!found) {
            System.out.println("해당 이름의 데이터를 찾을 수 없습니다.");
        }
    }

    public void showAllData() {
        for (int i = 0; i < phoneCnt; i++) {
            phone[i].basicData();
        }
    }
}

class Practice {
    private static void printUI() {
        System.out.println("선택하세요...");
        System.out.println("1. 데이터 입력");
        System.out.println("2. 데이터 검색");
        System.out.println("3. 데이터 삭제");
        System.out.println("4. 모든 데이터 보기");
        System.out.println("5. 프로그램 종료");
        System.out.print("선택: ");
    }

    public static void main(String[] args) {
        PhoneInfoHandler handler = new PhoneInfoHandler(10);
        int user = 0;

        Scanner sc = new Scanner(System.in);

        while (user != 5) {
            printUI();
            user = sc.nextInt();
            sc.nextLine();

            switch (user) {
            case 1:
                handler.addPhone();
                break;
            case 2:
                System.out.println("데이터 검색을 시작합니다.");
                System.out.print("이름: ");
                String searchName = sc.nextLine();
                handler.searchDataByName(searchName);
                break;
            case 3:
                System.out.println("데이터 삭제를 시작합니다.");
                System.
out.print("이름: ");
                String deleteName = sc.nextLine();
                handler.deleteDataByName(deleteName);
                break;
            case 4:
                System.out.println("모든 데이터를 출력합니다.");
                handler.showAllData();
                break;
               default:
                System.out.println("잘못 선택하셨습니다.");
            }
        }
    }
}
  • 제일 상위 클래스에 있는 클래스로 배열을 만들어서 그 배열의 인덱스 안에 상속받는 클래스들을 객체화 시켜서 넣는 개념이 처음에는 익숙하지 않았는데, 슬슬 감을 잡고 있는것같다. 사용자가 입력한 값을 배열에 넣을 때 메소드를 나눠야하는지 약간 헤맸는데 ..그래도 한 다음에 삭제가 좀 어려웠다.. 아직도 보고해야하는 난 새싹..

    • 그냥 삭제 시킬 배열위로 오른쪽 인덱스 덮어쓰기하면 되는데.. 그러고 마지막 배열은 빼주고..허허

    • 그리고 생각보다 내 오타가 너무 많아서 화딱지가 났다..휴 하나하나 신중하게 타이핑 해야겠다고 느꼈다..

그리고 순차배열로 넣으라는게 무슨 말인지 몰라서.. 그리고birth도 뭐에 쓰라는건지..

0개의 댓글