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);
}
}
어제와는 다르게 다른 메서드로 분류해서 메인메서드에서는 호출만하면 자동 실행되게끔 작성했다.
한번 했어서 큰 어려움은 없었다.
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;
}
}
}
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{}가 상속받으려면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메소드가 동적으로 선택되어 실행된다.
객체의 재사용 / 코드의 간결성 제공
extends라는 키워드를 통해 상속
상속받고자 하는 자식 클래스 이름 뒤에 extends 키워드를 붙이고 부모 클래스 이름을 적어준다.
자바는 다중 상속X > 단일 상속만 가능하다. > extends 키워드 뒤에 하나의 부모 클래스만 올 수 있다.
자식 클래스는 부모 클래스로부터 메소드와 필드를 물려받아 사용 / 부모 클래스는 자식 클래에서 정의한 메소드나 필드를 사용하지 x (자식 = 자신 + 부모 / 부모 = 자신)

Phone > 상위(super) 클래스
SmartPhone - 하위(sub) 클래스
class SmartPhone extends Phone{ }
Main(String[] args){
SmartPhone sp = nnew SmartPhone;
// SmartPhone 클래스 객체(sp) 생성
}
sp 라는 객체를 생성시, 하나의 객체(메모리)만 생성된다.
[public / protected / default / private]
private > default > protected > public 순으로 공유 범위가 넓어짐
오버라이딩[메소드 재정의] > 서로 상속관계로 이루어진 객체들 간의 관계에서 비롯
메소드 오버라이딩은 반드시 상속 관계를 가진 클래스에서 등장한다.

앞서 배운 this와 함께 객체를 참조할 수 있는 reference 변수
super라는 reference 변수는 현재 객체의 바로 상위인 super 클래스(상위 클래스)를 참조할 수 있다.
super 클래스의 생성자를 의미한다.
객체(메모리 공간)가 생성될 때는, 본인 클래스의 기본 생성자가 호출(저장)되고, 부모의 객체의 생성자도 호출(저장)된다. 그 후에는 멤버 변수와 멤버 메서드가 저장 > 그 객체 자체를 가리키는 주소가 참조 변수

부모 클래스가 선언한 기본 생성자에 인자 값이 있는 경우
상속받는 자식 클래스에서 부모 클래스의 기본 생성자에 인자 값을 넣어 선언해야한다.
[부모 클래스 생성자에 인자가 없는 경우]
- 자식 클래스 내 부모 클래스명() 선언 > 생략
[부모 클래스 생성자에 인자가 있는 경우]
- 자식 클래스 내 부모 클래스명(인자) 선
상속 관계에 있는 객체의 자료형은 자식 클래스의 클래스명을 참조 자료형으로 사용하는데 부모 클래스의 자료형으로 변경할 수 있다. 이것을 참조 자료형 형 변환이라고 한다. 객체가 생성된 후 부모 클래스의 자료형을 사용하면 호출할 수 있는 범위가 부모 클래스의 멤버 변수, 멤버 메서드로 한정된다.
참조 자료형 형 변환을 통해 다형성(Polymorphism)을 구현할 수 있다. 다형성은 한 객체가 여러 모습을 가질 수 있다는 것을 의미한다. 다형성을 자바 언어 측면에서 살펴보면 한 객체가 여러 타입이 될 수 있다는 것을 의미한다.
자식 클래스 -> 부모 클래스 타입 형 변환, 계층 구조 내 하위 클래스에서 상위 클래스로 단계가 높아짐.
참조 자료형의 수준을 높이기 때문에 자식 클래스의 참조 변수명만 기입.
부모 클래스 -> 자식 클래스 타입 형 변환, 계층 구조 내 상위 클래스에서 하위 클래스로 단계가 낮아짐.
일부러 참조 자료형의 수준을 낮추기 때문에 부모 클래스의 참조 변수명 앞에 자식 클래스의 (참조 자료형)을 캐스팅해야 함.

한 객체의 참조 자료형의 형 변환이 일어나도, 객체의 메모리에 저장되어 있는 멤버 변수와 메서드 등... 데이터에 대한 손실 및 추가사항은 없다. 다만 호출할 수 있는 범위가 변동될 뿐이다.
업캐스팅 할 경우, 참조 자료형은 부모 클래스이므로, 호출 범위가 줄어들기에 자식 클래스 내 멤버 변수와 멤버 메서드는 호출하지 못한다.
하지만 메서드 재정의(Overriding) 한 경우에는, 자식 클래스 내에 있는 멤버 변수나 멤버 메서드를 호출 가능.
변수에 final을 적용하면 상수지만, 메소드나 클래스 등에 붙으면 수정될 수 없음을 의미한다.
클래스, 필드, 메소드 선언시 사용
final 키워드가 메소드에 붙게 되면, 오버라이딩 할 수 없다.final 키워드가 클래스에 붙게 되면, 더 이상의 상속 확장은 불가능하다.구체적인 개념으로부터 공통된 부분들만 추려내어 일반화할 수 있도록 하는것을 의미
일반적으로 사용할 수 있는 단계가 아닌 아직 미완성적 개념인 것
일반 클래스와 달리 미완성되어있는 클래스로
객체 생성이 불가능하다.
상속관계를 맺은 자식 클래스가 객체로 생성되어야 사용이 가능하다.

추상 클래스가 단 한개라도 존재한다면, 그 클래스는 추상 클래스로 선언(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으로 접근제어지시자를 줘야한다.
추상 클래스는 일반적으로 한 개 이상의 추상 메소드를 갖는다.
추상 메소드는 일반 메소드와 다르게 메소드가 수행할 코드를 가지고 있지 x

추상 클래스들 간에도 상속이 가능하다. 일반 클래스들 간의 상속과 유사하지만 추상 클래스들 간의 상속에서는 상속받은 추상 메소드들은 꼭 재정의할 필요 없다.
클래스들이 필수로 구현해야 하는 추상 자료형 > 객체의 사용 방법을 가이드라인 하는 것
자바의 인터페이스는 추상 메소드와 상수로만 이뤄져있다 > 구현된 코드가 없기때문에 당연히 인터페이스로 인스턴스도 사용 x

interface라는 키워드를 붙여서 만든다.
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 등... 강사님께서 자바에서 기본적으로 제공하는 일부의 클래스에 대한 내용과 메서드는 암기하라고 하셨다.
패키지 : 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)이라고 한다.
패키지 : java.lang.StringBuffer
final class
문자열 가공할 때 사용.
String(참조 자료형)은 '문자열 불변의 법칙'이라는 특성을 가지고 있어 문자열을 가공(추가/수정) 할 때마다 객체를 항상 생성해야 하며, 이로 인해 쓰레기 객체가 발생하여 메모리를 효율적이게 관리하지 못한다.
자바에서는 이렇게 발생한 쓰레기 객체를 사용하지 않고, 일정 시간이 지난 후에는 삭제하며 메모리를 효율적이게 관리할 수 있도록 StringBuffer 사용을 권장한다.
insert() 메서드
원하는 위치(인덱스 값)에 데이터 추가하는 메서드
인자 - 위치(인덱스 값), 추가할 데이터
append() 메서드
기존 문자열 바로 뒤에 문자열 추가.
인자 - 추가할 데이터
replace() 메서드
특정 위치(인덱스 값)부터 특정 위치(인덱스 값-1)까지의 문자열을 지정한 문자열로 대체하여 변경.
인자 - 위치(인덱스 값), 위치(인덱스 값), 변경할 데이터
deleteCharAt() 메서드
특정 위치(인덱스 값)에 있는 데이터 삭제.
인자 - 위치(인덱스 값)
delete() 메서드
특정 위치(인덱스 값)부터 특정 위치(인덱스 값-1)까지의 문자열을 삭제.
인자 - 위치(인덱스 값), 위치(인덱스 값)
StringBuffer 클래스를 사용하면, String 클래스처럼 문자열이 바뀔 때마다 객체를 생성할 필요 없이 하나의 객체로 메서드문만 수행하여 문자열 가공이 가능.
문자열 가공(데이터 수정)이 완료되면, 최종 문자열을 StringBuffer 자료형에서 String 자료형으로 바꿔서 사용하면 된다.
패키지 : 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
패키지 : 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
패키지 : 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
패키지 : java.text.SimpleDateFormat
일반 class
extends DateFormat
객체를 생성할 때 생성자 인자 값에 날짜 형식 표(Date and Time Patterns)를 참고하여 데이터를 입력하여 날짜를 구할 때 사용하는 클래스.
format() 메서드
생성한 날짜를 문자열로 형식화할 때 사용.
반환값 - String
패키지 : java.util.Caledar
추상 class
필드 내 변수(년/월 등...)가 상수처리, 거의 대문자
년/월/일/시/분/초 데이터를 따로 구하여 사용할 때에는 Date 클래스보다는 Calendar 클래스를 활용.
getInstance() 메서드
현재 기준 날짜를 확인할 때 사용하는 메서드
java.util.GregorianCalendar[time=163...
시간에 이용되는 모든 데이터의 단위를 가져온다.
MONTH = 0~11 (컴퓨터에서는 0월~11월로 표기하기 때문에, 현실 시간을 불러오기 위해서라면 항상 MONTH 값에 +1을 해줘야 한다.)
반환값 - static Caledar
get() 메서드
getInstance() 메서드로 확인한 날짜 데이터(주어진 달력 필드의 값) 값을 반환할 때 사용하는 메서드.
반환값 - int
Friend 클래스
이름
전화번호
주소
메소드
showData : 모든 데이터(전체 제이터)를 출력하는 메소드
showBasicInfo : 기본 데이터(일부 데이터)를 출력하는 메소드
HighFriend 클래스 (Friend 클래스 상속)
직장
메소드
showData : 모든 데이터(전체 제이터)를 출력하는 메소드
showBasicInfo 메소드에서 이름, 전화번호, 직장을 출력
UnivFriend 클래스 (Friend 클래스 상속)
전공
메소드
showData : 모든 데이터(전체 제이터)를 출력하는 메소드 :이름 전번 주소 전공
showBasicInfo 메소드에서 이름과 전공학과를 출력 : 이름 전공
** 메뉴 선택 **
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 라고 키워드를 붙인다면 객체 생성할 수 없다.
소스코드에 추가해서 사용할 수 있는 메타 데이터의 일종
메타 데이터: 애플리케이션이 처리해야할 데이터가 아닌, 컴파일 과정과 실행과정에서 코드를 어떻게 처리해야하는지 알려주기 위한 추가 정보
보통'골뱅이(@)' 기호를 앞에 붙여 사용
컴파일러에게 코드 작성 문법 에러를 체크하도록 정보 제공
소프트웨어 개발 환경이 빌드나 배포시 코드를 자동으로 생성할 수 있도록 정보 제공
런타임에 특정 기능을 실행하도록 정보를 제공
메소드를 오버라이드하겠다는 의미 > 메소드 선언 앞에 붙여준다.
@Override
public void getInfo() {
System.out.println("test");
}
이 메소드를 사용하는 애플리케이션을 컴파일 할 경우 컴파일 경고 발생
컴파일러 경고를 출력하지 않도록 설정한다.
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() + "자리 숫자입니다.");
}
}
}
}
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;
}
}
}
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;
}
}
처음에 중심을 어떻게 기준으로 새우는지 고민했는데, 그냥 인덱스의 길이를 /2 하면 됐던거였다.
다른 메소드로 만들 생각은 없었는데 챗 지피티의 도움으로 이렇게 만들었다.
미드를 와 사용자 입력값이 같으면 출력하는 것은 알았는데 그 후에 작거나 크면, 시작값이나 끝 값을 해당 기준값으로 시작하면 되는줄 알았는데 거기에 +1 하고 -1 을 해야하는것이였다.
user == num[mid]: 현재 중간 값이 찾는 값과 일치하면 찾았으므로 반환합니다.
user > num[mid]: 찾는 값이 중간 값보다 크다면, 찾는 값은 중간 값보다 오른쪽에 있을 가능성이 있습니다. 따라서 검색 범위를 현재 중간 값의 오른쪽으로 좁힙니다. (first = mid + 1)
user < num[mid]: 찾는 값이 중간 값보다 작다면, 찾는 값은 중간 값보다 왼쪽에 있을 가능성이 있습니다. 따라서 검색 범위를 현재 중간 값의 왼쪽으로 좁힙니다. (end = mid - 1)

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도 뭐에 쓰라는건지..