Java 입문 클래스 4회차 미션

    4회차 미션

    배운내용,깨달은 점

    클래스의 활용

    https://transfer-kk.tistory.com/55

     

    자바 명명 규칙

    자바 코드를 작성하며 클래스/변수/메서드 명을 제대로 작성해야 나중에 큰 프로젝트를 할 때 힘들지 않다고 한다. 연습용 코드를 짜더라도 제대로 된 이름을 사용하여 이름 짓는 방법을 숙달하

    transfer-kk.tistory.com

    https://transfer-kk.tistory.com/56

     

    의미 있는 이름

    의미 있는 이름 - 의도를 분명히 밝히기 - 의도를 분명히 하는 변수명을 짓는 것이 오래걸려도 그 이름을 지어 절약하는 시간이 더 많기 때문 - 그릇된 정보를 피하자 - 널리 쓰이는 의미가 있는

    transfer-kk.tistory.com

    https://transfer-kk.tistory.com/57

     

    하나의 메서드가 하나의 기능을 수행해야 하는 이유

    1. 메서드 명만 보더라도 어떤 기능을 수행하는 메서드인지 명확하게 알 수 있다. - 기능의 단위가 짧고 명확할 수록 기능을 대변하는 이름 짓기도 수월하다 - 잘 지은 메서드 명은 코드의 가독성

    transfer-kk.tistory.com

    https://transfer-kk.tistory.com/58

     

    디미터 법칙

    디미터 법칙 : 모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다.(최소한의 지식 원칙) 객체는 자료를 숨기고 함수를 공개한다, 즉 객체는 조회 함수로 내부 구조를 공개하면 안된다는 의미

    transfer-kk.tistory.com

    어려웠던 점, 반성하고 싶은 점/개선할 방법

    class를 사용하는 이유를 정확히 모르고 사용하고 있었던 것 같습니다. 개발자들이 class가 왜 필요하여 class를 만든 것인 class는 어떻게 사용해야하는지 좀 더 공부해야할 것 같습니다.

    미션제출

    쪽집게 과외

    연습문제 1 아이유 프로필 출력하기

    // Main.java
    public class Main {
        public static void main(String[] args) {
            Person iu = new Person("아이유",30,true,40.5);
            iu.getPersonInformation();
        }
    }
    
    // Person.java
    public class Person {
        String name = "홍길동";
        int age = 0;
        boolean isStudent = false;
        double weight = 0.0;
        Person(String n,int a ,boolean u ,double w){
            name =n;
            age=a;
            isStudent = u;
            weight =w;
        }
        
        void getPersonInformation(){
            System.out.println("이름 : "+name);
            System.out.println("나이 : "+age);
            System.out.println("대학생인가요? : "+isStudent);
            System.out.println("몸무게 : "+weight);
    
        }
    
    }

    연습문제  2  아이유 프로필 출력하기2

    //Main.java
    public class Main {
        public static void main(String[] args) {
            // 1.
            Person iu1 = new Person("아이유", 30, true, 40.5);
            iu1.printProfile();
    
            // 2.
            Person iu2 = new Person("아이유", "30", true, "40.5");
            iu2.printProfile();
    
            // 3.
            Person iu3 = new Person("아이유", 30, true, "40.5");
            iu3.printProfile();
    
            // 4.
            Person iu4 = new Person("아이유", "30", true, 40.5);
            iu4.printProfile();
    
        }
    
    }
    
    // Person.java
    public class Person {
        String name = "홍길동";
        int age = 0;
        boolean isStudent = false;
        double weight = 0.0;
        Person(String n,int a ,boolean u ,double w){
            name =n;
            age=a;
            isStudent = u;
            weight =w;
        }
        Person(String n,String a ,boolean u ,String w){
            name =n;
            age=Integer.parseInt(a);
            isStudent = u;
            weight =Double.parseDouble(w);
        }
    
        Person(String n,int a ,boolean u ,String w){
            name =n;
            age=a;
            isStudent = u;
            weight =Double.parseDouble(w);
        }
    
        Person(String n,String a ,boolean u ,double w){
            name =n;
            age=Integer.parseInt(a);
            isStudent = u;
            weight =w;
        }
    
        void printProfile(){
            System.out.println("이름 : "+name);
            System.out.println("나이 : "+age);
            System.out.println("대학생인가요? : "+isStudent);
            System.out.println("몸무게 : "+weight+"\n");
    
        }
    
    }

    연습문제 3 계산기 만들기

    // Main.java
    
    public class Main {
        public static void main(String[] args) {
            Calculator calculator = new Calculator("제이슨");
            System.out.println("이 계산기는 " + calculator.getOwner() + "의 계산기입니다.");
            System.out.println("3+4는 " + calculator.add(3, 4) + "입니다.");
            System.out.println("6-2는 " + calculator.minus(6, 2) + "입니다.");
            System.out.println("2*9는 " + calculator.multiply(2, 9) + "입니다.");
            System.out.println("9/4은 " + calculator.divide(9, 4) + "입니다.");
            System.out.println("9/4은 " + calculator.divide("9", "4") + "입니다.");
        }
    
    }
    
    // Calculator.java
    
    public class Calculator {
        String name = "홍길동";
        Calculator(String n){
            name=n;
        }
        String getOwner(){
            return name;
        }
        int add(int a, int b){
            return a+b;
        }
        int minus(int a, int b){
            return a-b;
        }
        int multiply(int a, int b){
            return a*b;
        }
        double divide(int a, int b){
            return a/b;
        }
        double divide(String a, String b){
            int aValue = Integer.parseInt(a);
            int bValue = Integer.parseInt(b);
            return aValue/bValue;
        }
    }

    연습문제 4 학생들의 국어, 영어 점수 출력하기

    // Main.java
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
        public static void main(String[] args) {
            List<Student> students = new ArrayList<>();
            students.add(new Student("제이슨",87,92));
            students.add(new Student("레이첼",82,92));
            students.add(new Student("리사",92,88));
    
            for (Student s: students) {
                s.printScore();
            }
    
        }
    
    }
    
    // Student.java
    
    public class Student {
        String name = "홍길동";
        int koreanScore =0;
        int englishScore =0;
        Student(String n, int k, int e){
            name =n;
            koreanScore=k;
            englishScore=e;
        }
        void printScore(){
            System.out.println("이름 : "+name);
            System.out.println("국어 : "+koreanScore);
            System.out.println("영어 : "+englishScore+"\n");
    
        }
    }

     

    4회차 미션 : 책 대여하기

    // Main.java
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Library library = new Library(Arrays.asList(new Book("클린코드(Clean Code)"),
                new Book("객체지향의 사실과 오해"),
                new Book("테스트 주도 개발(TDD)")));
            library.rentBook();
        }
    }
    
    // Book.java
    
    public class Book{
        String bookName = "";
        boolean isPossibleRent = true;
        Book(String book){
            this.bookName=book;
            this.isPossibleRent= true;
        }
    
        String getBookName(){
            return bookName;
        }
        boolean getRentInformation(){
            return isPossibleRent;
        }
    }
    
    // Library.java
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Library {
        private List<Book> bookList;
    
        public Library(List<Book> books) {
            this.bookList = books;
        }
    
        void rentBook(){
    
            Scanner scanner = new Scanner(System.in);
    
            while(true){
                for (int i = 0; i<bookList.size();i++) {
                    System.out.println("대여할 책의 번호를 입력하세요.");
                    System.out.print(i + 1 + ". " + bookList.get(i).getBookName() + " - ");
                    if (bookList.get(i).getRentInformation() == true) {
                        System.out.println("대여 가능");
                    } else {
                        System.out.println("대여 중");
                    }
                }
    
                int rentBookNumber = scanner.nextInt();
    
                if(rentBookNumber<1||rentBookNumber>bookList.size()){
                    System.out.println("이 책은 도서관에 없습니다.");
                    break;
                }
    
                Book wantRentBook = bookList.get(rentBookNumber-1);
                if(wantRentBook.getRentInformation()) {
                    wantRentBook.isPossibleRent = false;
                    System.out.println("정상적으로 대여가 완료되었습니다.");
                }else {
                    System.out.println("대여 중인 책은 대여할 수 없습니다.");
                }
            }
        }
    }

    궁금한 점

    1. 제가 1학년때 객제지향프로그래밍 과목에서 get,set 함수를 사용했던 기억이 있어 get함수를 사용하였는데 검색하고 보니 get함수는 외부로부터 변수값에 직접적으로 접근하는것을 막기 위해서라고 합니다 저는 bookName과 isPossibleRent를 private를 사용하지 않고 선언하였는데 그러면 get 함수의 의미가 없어지는 것이 맞나요?

    2. this를 사용하신 이유도 private와 관련이 있는게 맞나요?

    3. 4회차 미션을 힌트를 보고 코드를 좀 고쳤는데 이 코드는 의도하신 바와 맞는지 궁금합니다!

    4. 멘토님이 쪽집게과외에서 주신 링크타고 글을 보다가

    https://tecoble.techcourse.co.kr/post/2020-04-26-Method-Naming/

    이런 글을 봤는데 여기에서 네이밍이 중요한이유->의도가 모호한코드에서의 코드중에

    List<int[]> list1 = new ArrayList<int[]>();

    이런 코드가 있었는데 멘토님이 제네릭에 데이터타입을 양쪽에 적지 말라고 하셨던게 생각나서 이분은 굳이 이렇게 하신 이유가 있으실까 싶어 궁금증이 들어 여쭤봅니다!

    5. 위의 글에서

    • 되도록이면 상태 데이터를 가지는 객체에서 데이터를 (get)하지 말고 객체에 메시지를 보내는 것을 추천한다.
    라고 하는 말이 있는데 이해가 잘 안되어서 이게 어떤말인지 궁금합니다..!
     

    예제를 해보았습니다.

    // Main.java
    
    public class Main {
        public static void main(String[] args) {
            Healer person1 = new Healer("모랄레스",60);
            Dealer person2 = new Dealer("레이너",80);
    
            Dealer.stimpack(); //Non-static method 'stimpack()' cannot be referenced from a static context
            Healer.heal(person2); //Non-static method 'stimpack()' cannot be referenced from a static context
        }
    }
    
    // Person.java
    
    public class Person {
        private String playerName = "홍길동";
        private int hp = 0;
    
        public void setPlayerName(String name){
            this.playerName = name;
        }
        public String getPlayerName(){
            return this.playerName;
        }
        public void setHp(int value){
            this.hp = value;
        }
        public int getHp(){
            return this.hp;
        }
    }
    
    // Healer.java
    
    class Healer extends Person{
        public Healer(String name, int blood){
            setPlayerName(name);
            setHp(blood);
        }
        void heal(Person person){
            System.out.print(this.getPlayerName()+"의 치유! => "+person.getPlayerName());
            System.out.print("HP : "+person.getHp()+" -> ");
    
            int personCurrentHp = person.getHp();
    
            person.setHp(personCurrentHp+10);
            System.out.println(personCurrentHp);
        }
    }
    
    // Dealer.java
    
    public class Dealer extends Person{
        public Dealer(String name, int blood){
            setPlayerName(name);
            setHp(blood);
        }
        void stimpack(){
            int currentHp = this.getHp();
            System.out.print(this.getPlayerName()+"의 스팀팩!");
            System.out.print("HP : "+currentHp +" -> ");
            this.setHp(currentHp-10);
            System.out.println(this.getHp());
        }
    }

    Main.java 파일에서

    Dealer.stimpack();
    Healer.heal(person2);

    인 부분에서 Non-static method 'stimpack()' cannot be referenced from a static context 에러가 나는데 이 에러를 풀기 위해서는 저 함수들을 static으로 바꾸어주어야 한다는 것은 알 것 같습니다. 하지만 static은 클래스의 멤버변수 중 모든 인스턴스에 공통적으로 사용해야하는 것에 붙여주어야한다고 하는데 저 함수들은 공통적으로 사용하는 것이 아니니 static을 붙이지 않는 것이 더 맞다고 생각합니다. 그렇다면 어떻게 코드를 고쳐야 할지가 궁금합니다. 아니면  제가 검색해서 이해한 내용이 잘못된 것일까요..?

    댓글