Back-End

[JAVA] 기초 공부 8

Minch13r 2025. 1. 13. 09:40
  1. 첫 번째 코드의 경우:
package day010.class01;

class Student {
}

public class Test01 {
}

  • 이것은 "톱레벨 클래스(Top-level Class)"라고 부릅니다.
  • Student 클래스와 Test01 클래스가 동등한 레벨에 있습니다.
  • 서로 독립적인 클래스입니다.
  1. 두 번째 코드의 경우:
package day010.class01;

public class Test01 {
    static class Student {
    }

    public static void main(String[] args) {
    }
}

  • 이것은 "정적 중첩 클래스(Static Nested Class)"입니다.
  • Student 클래스가 Test01 클래스 안에 들어있습니다.
  • 이때 static이 필요한 이유는:
    1. Student 클래스가 Test01의 인스턴스 없이도 사용될 수 있게 하기 위함입니다.
    2. main 메소드가 static이므로, 그 안에서 Student 클래스를 사용하려면 Student도 static이어야 합니다.

쉽게 비유하면:

  • 첫 번째 코드는 아파트 단지에 두 개의 동이 있는 것과 같습니다.
  • 두 번째 코드는 큰 아파트(Test01) 안에 작은 방(Student)이 있는 것과 같습니다.

static이 없다면:

만약 Student 클래스 앞에 static을 붙이지 않으면:

  1. Student 클래스는 Test01의 인스턴스가 있어야만 사용할 수 있습니다.
  2. static main 메소드에서 Student 클래스를 직접 사용할 수 없게 됩니다.

실제 사용 예시:

// 첫 번째 코드의 사용
Student student1 = new Student();

// 두 번째 코드의 사용
Test01.Student student2 = new Test01.Student();

이렇게 중첩 클래스를 사용하는 이유는:

  1. 관련된 클래스들을 논리적으로 그룹화할 수 있습니다.
  2. 캡슐화를 강화할 수 있습니다.
  3. 코드의 가독성과 유지보수성이 향상됩니다.

Static에 관련하여 요약 정리

static은 객체랑 무관할 때 안 붙고 안 무관하면 붙음

포켓몬스터 게임 start() → 기계와 관련 있어서 static이 붙음

몸통박치기() → 객체와 관련 있어서 static이 안 붙음


package day010.class01;

import java.util.Random;

class Student {
    String name; // 멤버변수
    int score; // 필드, 속성 attribute, property
    Student(){
        this.name="무명";
        this.score=0;
    }
    Student(String name){
        this.name = name;
        this.score = 0;
    }
    Student(String name, int score){
        this.name = name;
        this.score = score;
    }
    void printInfo(){ // 멤버함수, "메서드
        System.out.println("학생" + this.name + "은(는)" + this.score + " 점 입니다.");
    }
    // changeScore 함수를 불러내는게 Student라고 해서 이미 인자를 다 갖고 있어서 따로 선언 안 해도 됨.
    // 즉, 인자가 가벼워진다는 의미
    // Student 클래스 바깥이였으면 changeScore(String name) 이런식으로 불러와야 함
    void changeScore(){
        this.score = new Random().nextInt(101);
        System.out.println(this.name + " 학생의 점수가 변경되었습니다!");
    }
}

public class Test01 {
    public static void main(String[] args) {
        Student s1 = new Student("홍길동");
        Student s2 = new Student("임꺽정", 80);

        s1.printInfo();
        s2.printInfo();
    }
}

 

Student 클래스 안에서 객체를 호출하면 인자를 따로 선언 안 하고 this. 를 통해 가져오면 된다. 왜냐하면 함수가 Student 클래스 안에 있고 인자도 Student 클래스 안에 있기 때문이다. 만약 Student 클래스 바깥이였으면 ChangeScore(String name) 이런식으로 갖고와야 한다. 하지만 이런 경우에는 안 갖고와도 되기 때문에 인자가 가벼워진다고 생각하면 된다.


package day010.class01;

class Point{
    int x;
    int y;
    Point() {
        this(0,0); // 자기자신 객체를 가르킴. 자신과 똑같은 이름을 가진 함수를 불러냄
        // this()는 생성자가 되는거임
        // this.멤버변수 이거는 멤버변수 접근 연산자
        System.out.println("강아지");
    }
    Point(int x){ // 인자가 가장 많은 생성자를 재사용
        this(x,x);
        // 이미 만둘어둔 생성자를 호출하기는 하는데 앞에 있는게 없는 경우 0 적으면 됨
        System.out.println("고양이");
    }
    Point(int x, int y){ // 가장 인자가 많은 생성자 먼저 구현
        this.x = x;
        this.y = y;

        System.out.println("카피바라");
    }
}
public class Test02 {
    public static void main(String[] args) {
        Point p1 = new Point(1,2);
        Point p2 = new Point(1); // 12, 13, 17, 18, 19, 21, 15 순서
        Point p3 = new Point(); // 6, 7, 17, 21, 13, 15, 10 순서
    }
}

실행결과

생성자를 재사용하는 방법을 알아봤다


package day010.class02;

import java.sql.SQLOutput;

// 모래성 게임
class Game {
    String name;
    static int gameScore = 100; // 공유자원, 클래스변수, 멤버변수 아니기에 여기서 초기화

    Game(String name) {
        this.name = name;
    }

    void play(int score) {
        System.out.println(this.name + "이(가) 게임을 시도합니다...");
        Game.gameScore -= score;
        System.out.println("남은 모래성 : " + Game.gameScore);
        if (Game.gameScore <= 0) {
            System.out.println(this.name + "이(가) 실패!");
        } else {
            System.out.println(this.name + "이(가) 성공!");
        }
    }
}

public class Test01 {
    public static void main(String[] args) {
        Game p1 = new Game("티모");
        Game p2 = new Game("럭스");
        Game p3 = new Game("아무무");

        p1.play(90);
        p2.play(5);
        p3.play(10); // 기존이 100인데
        // 티모랑 럭스가 95를 가져가서 아무무가 못 가져가기에
        // 아무무는 실패한다고 보면 됨
    }

}
package day010.class02;

class Person {
    String name;
    static int money=10000; // 가족 계좌 정보 같은 개념
    Person(String name){
        this.name = name;
    }
    void pay(int money){
        if(money > Person.money){
            System.out.println("결제 실패");
            return; // 함수 더 이상 실행하면 안 됨
        }
        Person.money -= money;
        System.out.println(this.name + "님이 " + money + "원 결제했습니다.");
        System.out.println("잔액 : " + Person.money + "원");
    }
}

public class Test02 {
    public static void main(String[] args) {
        Person p1 = new Person("나");
        Person p2 = new Person("동생");
        Person p3 = new Person("엄마");
        Person p4 = new Person("아빠");

        p4.pay(5000);
        p3.pay(1000);
        p2.pay(4500);
        p1.pay(1000);
    }
}

package day010.class03;

import java.util.Random;

/*
책들을 생성할 수 있게 해주세요.
책의 속성은 제목,작가,가격으로 구성되어있습니다.
책을 생성할 때에는 제목을 무조건 등록해야합니다.
작가를 모를때에는 "작자미상"으로 등록합니다.
가격을 모를때에는 10000~20000원 사이로 등록해주세요.
단, 100원단위이하로는 설정하지않습니다.
ex) 만천원,만이천원 가능 / 만천오백원 불가능
책의 가격을 랜덤으로 재설정하거나,
사용자가 원하는가격으로 재설정할수있게 메서드를 구현해주세요.
책 정보를 출력해주세요.
*/
class Book {
    //제목, 작가, 가격 구성
    //오버로딩으로 작자미상 등록
    //가격 모를 때 랜덤으로 범위 선언 후 가격 지정((Random.nextInt(10) + 10) * 100)
    //조건문을 사용해서 가격 재설정
    String title; // 제목
    String author; // 작가
    int price; // 가격

    // 모든 정보 O
    Book(String title, String author, int price){
        this.title = title;
        this.author = author;
        this.price = price;
    }
    // 작가 정보 X
    Book(String title, int price){
        this(title, "작자미상", price);
    }

    // 가격 정보 X
    Book(String title, String author) {
        this(title, author, ((new Random()).nextInt(11) + 10) * 1000);
    }

    // 작가와 가격 정보 X
    Book(String title) {
        this(title, "작자미상", ((new Random()).nextInt(11) + 10) * 1000);
    }

    // 가격 랜덤
    void changeRandomPrice() {
        this.price = ((new Random()).nextInt(11) + 10) * 1000;
    }

    // 가격 직접 변경
    void changePrice(int price) {
        this.price = price;
    }

    // 책 정보 출력
    void bookInfo() {
        System.out.println("\n===== 책 정보 =====");
        System.out.println("제목 : " + title);
        System.out.println("작가 : " + author);
        System.out.println("가격 : " + price + "원");
        System.out.println("==================");
    }
    static void printChangeSout(){ // 객체랑 관련 없는 함수
        System.out.println("\n==============");
        System.out.println("★가격 변경 완료★");
        System.out.println("==============");
    }
}
public class Test01 {
    public static void main(String[] args) {
        Book book1 = new Book("궯뚧뤫쉡"); // 작가랑 가격 없는 내용 출력
        Book book2 = new Book("바보", "너"); // 가격만 없는 내용 출력
        Book book3 = new Book("변신", 12500); // 작가만 없는 내용 출력
        Book book4 = new Book("와우", "ㅋㅋ", 13000);

        book1.bookInfo();
        book2.bookInfo();
        book3.bookInfo();
        book4.bookInfo();

        Book.printChangeSout();

        book1.changeRandomPrice();
        book2.changePrice(13000);

        book1.bookInfo();
        book2.bookInfo();
        book3.bookInfo();
        book4.bookInfo();
    }
}
package day010.class03;

/*
자동차 자료형을 제작해주세요.
자동차는 차 주인의 이름,현재속도,최대제한속도를 필드로 갖습니다.
차 주인정보는 미등록시 자동차를 할당할 수 없습니다.
현재속도는 최초 등록시 0으로 세팅됩니다.
최대제한속도는 미등록시 120으로 자동설정됩니다.
속도를 원하는만큼 높여주는 speedUp() 메서드와
10만큼 속도를 낮춰주는 speedDown() 메서드를 구현해주세요.
자동차는 최대제한속도를 초과하여 달릴수없습니다.
자동차의 현재속도를 출력할수있게 메서드를 구현해주세요.
*/

class Car {
    // 차 주인 이름, 현재속도, 최대제한속도 선언
    // 차 주인이름을 입력해야 자동차 할당 가능, 안 하면 할당 X
    // 최초 등록시 현재 속도는 0으로 세팅
    // 최대제한속도 미등록시 120으로 자동설정
    // 속도 올려주는 speedUp() 함수 선언
    // while()이랑 scanner를 통해서 입력받고 +=로 올려주기
    // 속도 10만큼 낮춰주는 speedDown() 함수 선언
    // 자동차 최대제한속도 못 넘게, 넘으면 최대속도로 표시
    // 함수로 현재속도 출력
    String name;
    int speed;
    int max;
    Car(String name){
        this(name, 120);
    }
    Car(String name, int max){
        this.name = name;
        this.speed = 0;
        this.max = max;
    }
    void speedUp(int speed){
        this.speed+=speed;
        if(this.speed>this.max){
            this.speed=this.max;
            System.out.println("과속주의!");
        }
        System.out.println("속도++");
    }

    void speedDown(){
        this.speed-=10;
        if(this.speed < 0){
            this.speed=0;
            System.out.println("멈춤...");
        }
        System.out.println("속도---");
    }

    void printInfo(){
        System.out.println(this.name+"님의현재속도 : " + this.speed);
    }

}

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

    }
}
package day010.class03;

/*
자동차 자료형을 제작해주세요.
자동차는 차 주인의 이름,현재속도,최대제한속도를 필드로 갖습니다.
차 주인정보는 미등록시 자동차를 할당할 수 없습니다.
현재속도는 최초 등록시 0으로 세팅됩니다.
최대제한속도는 미등록시 120으로 자동설정됩니다.
속도를 원하는만큼 높여주는 speedUp() 메서드와
10만큼 속도를 낮춰주는 speedDown() 메서드를 구현해주세요.
자동차는 최대제한속도를 초과하여 달릴수없습니다.
자동차의 현재속도를 출력할수있게 메서드를 구현해주세요.
*/

class Car {
    // 차 주인 이름, 현재속도, 최대제한속도 선언
    // 차 주인이름을 입력해야 자동차 할당 가능, 안 하면 할당 X
    // 최초 등록시 현재 속도는 0으로 세팅
    // 최대제한속도 미등록시 120으로 자동설정
    // 속도 올려주는 speedUp() 함수 선언
    // while()이랑 scanner를 통해서 입력받고 +=로 올려주기
    // 속도 10만큼 낮춰주는 speedDown() 함수 선언
    // 자동차 최대제한속도 못 넘게, 넘으면 최대속도로 표시
    // 함수로 현재속도 출력
    String name;
    int speed;
    int max;
    Car(String name){
        this(name, 120);
    }
    Car(String name, int max){
        this.name = name;
        this.speed = 0;
        this.max = max;
    }
    void speedUp(int speed){
        this.speed+=speed;
        if(this.speed>this.max){
            this.speed=this.max;
            System.out.println("과속주의!");
        }
        System.out.println("속도++");
    }

    void speedDown(){
        this.speed-=10;
        if(this.speed < 0){
            this.speed=0;
            System.out.println("멈춤...");
        }
        System.out.println("속도---");
    }

    void printInfo(){
        System.out.println(this.name+"님의현재속도 : " + this.speed);
    }

}

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

    }
}

package day010.class06;

import java.util.Scanner;

// 객체 배열
class Student {
    static int studentNum=1001;
    int num; // PK 값은 사용자가 부여 xxx
    String name; // 이름
    int score; // 점수
    char grade; // 학점
    Student(String name){
        this(name,0);
    }
    Student(String name,int score){
        this.num=Student.studentNum++; // 번호가 1001부터 순차적으로 증가
        this.name=name;
        this.score=score;
        this.setGrade(); // 학점은 점수에 따라 측정됨
        System.out.println("학생 정보 생성 완료!");
    }
    void printInfo() { // 정보 출력 함수
        System.out.println("번호 : "+this.num);
        System.out.println("이름 : "+this.name);
        System.out.println("점수 : "+this.score);
        System.out.println("등급 : "+this.grade);
    }
    void changeScore(int score) { // 점수 변경
        this.score=score; // score로 입력된 정수가 this.score을 통해 다시 배정
        this.setGrade(); // 점수 -> 학점 배정
        System.out.println("학생 정보 변경 완료!");
    }
    void setGrade() {
        this.grade='C'; // 원래 C
        if(60<=this.score && this.score<80) {
            this.grade='B'; // 60~79 => B
        }
        else if(80<=this.score) {
            this.grade='A'; // 80 이상 A
        }
    }
}

public class Test01 {
    // '학생(객체)'와 무관한 기능 --->> 함수
    public static boolean isFull(int cnt,Student[] datas) {
        if( cnt >= datas.length ) { // 학생수가 배열의 크기보다 크면 에러처리
            return true;
        }
        return false; // 아닌경우 저장 가능하게 false 반환
    }
    // 성적 입력 유효성 검사 --->> 함수 ===>> VIEW

    public static void main(String[] args) {

        Student[] datas=new Student[3]; // 배열 크기 3

        datas[0]=new Student("티모");
        datas[1]=new Student("모르가나",68);
        // 샘플 데이터

        int cnt=2; // 현재 학생수 2명

        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.println("5. 등급으로 학생 검색");
            System.out.println("6. 이름으로 학생 검색");
            System.out.println("0. 프로그램 종료");

            System.out.print(">> ");
            int menu=sc.nextInt();
            if(menu==0) {
                break;
            }

            else if(menu==1) { // 전체출력
                for(int i=0;i<cnt;i++) {
                    datas[i].printInfo();
                }
            }

            else if(menu==2) { // 번호로 학생 검색
                System.out.print("번호입력 >> ");
                int num=sc.nextInt();

                // datas == 배열 == 학생부
                // datas[i] == 배열[인덱스번호] == 배열의 요소 == 학생 == 학생 객체
                // datas[i].num == 학생.번호 == 학생 객체.멤버변수
                boolean flag=false;

                for(int i=0;i<cnt;i++) {
                    if(num == datas[i].num) {
                        datas[i].printInfo();
                        flag=true;
                        break;
                    }
                }

                if(!flag) {
                    System.out.println("해당 학생은 없습니다...");
                }
            }
            else if(menu==3) { // 학생추가
                if(isFull(cnt,datas)) {
                    System.out.println("학생부 데이터에 저장공간이 없습니다!");
                    continue;
                }

                System.out.print("이름 입력 >> ");
                String name=sc.next();
                System.out.print("성적을 입력하시겠습니까? Y/N >> ");
                String ans=sc.next();
                if(ans.equals("Y")) {
                    System.out.print("성적 입력 >> ");
                    int score=sc.nextInt();
                    datas[cnt++]=new Student(name,score);
                }
                else {
                    datas[cnt++]=new Student(name);
                }
            }

            else if(menu==4) { // 성적변경
                System.out.print("번호입력 >> ");
                int num=sc.nextInt();

                // datas == 배열 == 학생부
                // datas[i] == 배열[인덱스번호] == 배열의 요소 == 학생 == 학생 객체
                // datas[i].num == 학생.번호 == 학생 객체.멤버변수
                boolean flag=false;

                int i; // scope 이슈 해결
                for(i=0;i<cnt;i++) {
                    if(num == datas[i].num) {
                        datas[i].printInfo();
                        flag=true;
                        break;
                    }
                }
                if(!flag) {
                    System.out.println("해당 학생은 없습니다...");
                    continue;
                }
                System.out.print("변경할 점수입력 >> ");
                int score=sc.nextInt();

                datas[i].changeScore(score);
            }

            // 등급으로 학생 검색
            else if(menu == 5){
                System.out.print("등급을 입력해주세요(A/B/C) >>");
                String ans = sc.next();
                boolean flag = false;

                //https://stackoverflow.com/questions/9159358/implicit-cast-to-string-tostring-and-int
                for(int i=0; i<cnt; i++) {
                    //배열은 char형식 ""를 추가해줌응로써 String으로 묵시적 형변환
                    if((datas[i].grade + "").equalsIgnoreCase(ans)) {
                        datas[i].printInfo();
                        flag = true;
                    }
                }
                if(!flag) {
                    System.out.println(ans + " 등급의 학생이 없습니다...");
                }


            }

            // 이름으로 학생 검색
            else if(menu == 6) {
                System.out.print("검색할 학생 이름을 입력해주세요 >> ");
                String ans = sc.next();
                boolean flag = false;

                for(int i=0; i<cnt; i++) {
                    if(datas[i].name.equals(ans)) {
                        datas[i].printInfo();
                        flag = true;
                    }
                }
                if(!flag) {
                    System.out.println(ans + " 학생은 존재하지 않습니다...");
                }
            }
        }
    }
}

'Back-End' 카테고리의 다른 글

[JAVA] 기초 공부 10  (1) 2025.01.15
[JAVA] 기초 공부 9  (1) 2025.01.14
[JAVA] 기초 공부 8(객체지향)  (0) 2025.01.10
[JAVA] 기초 공부 7(MVC, 오버로딩)  (1) 2025.01.09
[JAVA] 선택 정렬 함수 이용해서 코드짜기  (0) 2025.01.08