초록꼬마의 devlog
article thumbnail

2021.10.22(금)

🌿 배열

🌱 배열 복사

출처: https://i.ibb.co/fk2p7ch/copy.png

 

출처: https://i.stack.imgur.com/AWKJa.jpg

 

✔️ 얕은 복사 = 배열의 주소 값만 복사 → 참조 대상(배열의 내용물)은 동일한 것을 가리키고 있음

✔️ 깊은 복사 = 동일한 새로운 배열을 하나 생성해서 실제 내부값까지 복사

방법1) 반복문
방법2) System.arraycopy() 메서드 사용
방법3) Arrays.copyOf() 메서드 사용
방법4) clone() 메서드 사용

비둘기집 원리 = hashcodes가 같다고 해서 둘이 같다고 할 수는 없으나, hashcodes가 다르면 둘은 다름

🌿 객체

- Java는 객체(object) 지향(프로그래밍 방법 중의 하나)을 지원하는 프로그래밍 언어

- 객체 = 실제로 존재하는 것(사물 또는 개념) → 객체 지향 이론 = 실제 세계는 사물/객체로 이루어져 있음 + 발생하는 모든 사건들은 사물 간의 상호작용 

- 객체 지향 언어의 특징

1. 코드의 재사용성이 높다

2. 코드의 관리가 용이하다 ← 코드 간의 관계를 이용해서 적은 노력으로 쉽게 코드 변경 가능

3. 신뢰성이 높은 프로그래밍을 가능하게 한다 ← 캡슐화/정보 은닉, 코드의 중복 제거 등

 

🌱 추상화

// 토끼들을 추상화(abstraction)해서 만든 클래스(토끼가 어떻게 생겼는지 성질 등)
public class Rabbit { // public = 다른 패키지에서도 이 클래스를 접근할 수 있도록 하는 접근
    // Rabbit 클래스의 모양 만들기

    // [필드부]
    // 토끼들의 성질은 아주 많지만, 특정 토끼를 구분하기 위해 필요한 성질 추출 = (멤버/인스턴스)변수, 필드
    // 접근제한자 자료형(기본+사용자 정의) 필드이름;
    // 접근(access)제어/한자(modifier): 이 필드에 접근할 수 있는 범위를 제한할 수 있음; public(공공의 -> 외부(다른 패키지)에서 사용 가능) > protected > default > private(개인의, 사적인 -> 직접 접근 막힘;가장 많이 쓸 것임); 클래스 안에서 필드 선언 시 반드시 접근제한자 써줘야 함
    public String name;
    public int age;
    public double weight;
    public char gender;
    public boolean isBig;
    public String eyesColor;
    public String noseColor;
    public String bodyColor;
    public String dressColor;

    // [생성자부]

    // [메소드부]
    // 토끼의 성질을 변화시킬 토끼의 행동 = 메소드
    public void eat(int weight) { // 토끼 객체의 체중(성질)을 변화시키는 행동
                                  // 괄호 안 = 마술상자/메소드에 들어올 input; 자료형도 입력
        this.weight += weight; // 토끼 체중은 계속 늘어나는 게 가능한 것으로 해둠
        // this. = 이것(토끼 객체)의 체중 != 입력값으로 들어오는 체중
        // 좌항의 weight는 형광하늘색(클래스의 멤버변수) vs 우항의 weight는 군청하늘색(메소드에 input됨) 
    }

    public void jump() {
        if ( weight > 200 && weight > 10.39) { // 체중은 무한히 감소할 수 없으므로 조건 걸기 -> 조건문; 토끼의 최소 건강 체중 && 빼려고 하는 무게보다 클 때
            weight -= 10.39;
        } else {
            System.out.println("더 살 못 빼요, 밥 주세요~");
        }
    }
    // 컴퓨터는 실수를 완벽히 표현하지 못함 -> double형 마지막 자리에 작은 숫자가 남아서, 예상한 값과 달리 소숫점 아래 작은 수가 나타남 
}

🌱 클래스

✔️ 구조

field/멤버 변수/인스턴스 변수 + 생성자(constructor)부 + method부

✔️ 필드/멤버/인스턴스 변수

상태를 나타냄

✔️ 메소드

동작을 나타냄

public class Run { // 클래스 영역 시작

    public static void main(String[] args) { // main메소드 영역 시작

        /* 객체(object) 지향(oriented) 프로그래밍(programming): 현실세계에서 독립적인 존재(객체)들 간의 상호작용(행위)을 프로그래밍 언어를 통해 코드를 구현하는 것
         * 객체: ____(앞으로 계속 배워나갈 것) -> 클래스에 정의된 내용대로 new 연산자를 통해 메모리(heap 영역)에 생성된 것 -> 주소값이 들어감
         * 
         * 구현하고자 하는 프로그램 상의 객체(변수)를 만들기/생성하기 위해서는 클래스라는 틀을 먼저 만들어야 함; 객체를 만들기 위해서는 클래스가 있어야 함
         * 클래스 = blueprint(설계도), 붕어빵 틀, 공장; 각 객체/객체들의 모양/속성(정보/변수+행위/기능)을 담아내는 그릇/틀; value(값; 값을 담고 있는) object -> (재료만 있다면) 똑같은 것을 여러 개 만들어낼 수 있음 
         */

        Person eunyoungKang; // Person이라는 내가 만든(사용자 정의) 참조자료형(=클래스); Person이라는 클래스 형태의 자료형 -> 참조자료형으로 선언한 변수 'eunyoungKang' = 객체

        // 클래스 하나를 가지고 Person 형태를 가진 객체 여러 개 만들어냈음
        Person 토미;
        Person 미피;
        Person 판다;
        Person 해피;
        Person 무민;
        Person 스노크메이든;
        Person 혁;

        /* 클래스는 어떻게 만드는가?
         * Rabbit(클래스) 우리집토끼(객체)
         * 우리집토끼의 특징:
         *   이름은 해피 -> String name;
         *   눈이 까맣다 -> String eyesColor;
         *   코가 분홍색이다 -> String noseColor;
         *   몸은 베이지색이다 -> String bodyColor;
         *   옷은 분홍색이다 -> String dressColor;
         *       literal/값
         * 단계1) 이러한 멤버변수들을 포함하는 토끼(Rabbit) 클래스 만들기
         */

        // 단계2) 우리집토끼 객체("ourRabbit") 만들기
        Rabbit ourRabbit = new Rabbit();
        // Rabbit 클래스 = 사용자 정의 참조자료형 -> 이 클래스/자료형의 변수에는 RAM의 heap 영역의 주소값이 저장되어 있음
        // 객체(ourRabbit) 생성 시 new 키워드 사용 -> 메모리의 heap 영역 공간에 할당됨; 객체를 생성하는 연산자 new의 결과 = 생성된 객체의 주소

        // 토끼 클래스의 두번째 객체(우리집토끼의 친구) 만들어주기
        Rabbit rabbit2 = new Rabbit();

        // 단계3) 우리집토끼(객체)의 성질 입력
        ourRabbit.name = "해피";
        // 참조/직접접근 연산자 . 사용해서 우리집토끼 객체에 접근
        // 접근(access)제어자(modifier): public 등을 통해 다른 패키지의 클래스에서도 접근 가능할 수 있도록 -> 객체에 직접 접근해서 값 대입해줌 (vs chap02 캡슐화)
        ourRabbit.age = 4;
        ourRabbit.weight = 450.95;
        ourRabbit.eyesColor = "검은색";
        ourRabbit.noseColor = "분홍색";
        ourRabbit.bodyColor = "베이지색";
        ourRabbit.dressColor = "분홍색";

        System.out.println(ourRabbit); // 객체 ourRabbit이 만들어져있는(?) heap 영역의 주소가 출력됨

        // 객체의 각 성질(?) 값이 잘 입력되었는지 직접 접근해서 조회 및 출력해서 확인해보기
        System.out.println(ourRabbit.name + "의 눈 색깔은 " + ourRabbit.eyesColor + ", 몸 색깔은 " + ourRabbit.bodyColor + 
                ", 코 색깔은 " + ourRabbit.noseColor + ", 나이는 " + ourRabbit.age + "세, 몸무게는 " + ourRabbit.weight + "g입니다 ^^");

        // 객체2(우리집토끼의 친구 토끼)의 성질 입력
        rabbit2.name = "토미";
        rabbit2.age = 5;
        rabbit2.weight = 195.87;
        rabbit2.eyesColor = "갈색";
        rabbit2.noseColor = "황토색";
        rabbit2.bodyColor = "분홍색과 흰색";
        rabbit2.dressColor = "없음";

        System.out.println(rabbit2);
        System.out.println(rabbit2.name + "의 눈 색깔은 " + rabbit2.eyesColor + ", 몸 색깔은 " + rabbit2.bodyColor + 
                ", 코 색깔은 " + rabbit2.noseColor + ", 나이는 " + rabbit2.age + "세, 몸무게는 " + rabbit2.weight + "g입니다 ^^");

        // 위와 같이 직접적으로 접근해서 값을 대입하거나 조회 시 vs 토끼의 키는 성장환경, 식습관, 운동 등 행동(메소드)에 따라 달라져야 함; 직접 접근 시 누군가 악의적으로/불합리하게 값 바꾸는 등 보안의 문제 생길 수 있음
//        ourRabbit.weight = -3;
//        System.out.println(ourRabbit.name + "의 몸무게는 " + ourRabbit.weight + "g입니다 ^^");
        // 직접 접근을 막는 방법 = 정보 은닉(객체 지향 설계 원칙 중 하나) -> 정보 은닉을 하기 위한 기술 중 하나 = 캡슐화(encapsulation)

        ourRabbit.eat(5); // eat(먹기) 행동 ou 매개변수 있는 메소드로 만든 경우 메소드에 의해 내가 먹인(=메소드의 인자/argument로 input한 정수값)만큼 살찜
        System.out.println(ourRabbit.name + "의 몸무게는 " + ourRabbit.weight + "g입니다");

        rabbit2.eat(2);
        rabbit2.eat(3);
        rabbit2.eat(1);
        System.out.println(rabbit2.name + "의 몸무게는 " + rabbit2.weight + "g입니다");

        ourRabbit.jump(); // jump(뛰기 운동) 행동/메소드에 의해 체중 감소
        System.out.println(ourRabbit.name + "의 몸무게는 " + ourRabbit.weight + "g입니다");

    } // main메소드 영역 끝

} // 클래스 영역 끝

📗 소감

  • 드디어 객체! 객체 지향 프로그래밍부터가 혼자서도 아직 공부하지 않았던 부분이라 긴장도 되고 궁금해서 수업을 더더욱 집중해서 듣고 개념들의 구조를 머리 속으로 그리며 최대한 이해하려고 했다.
  • 그런데 그 전에 배열 복사를 완벽히 이해하지 못해서 앞으로 이해가 잘 안 되는 부분이 많아질까봐 걱정이다. 밀리지 말고, 오늘 개념들 잘 복습하고, 객체 지향 예습도 해야겠다!
  • 숙제도 고민해서 멋지게 풀어보자!

📗 homework:
Part1) 배열 및 제어문

  1. 문자열을 입력 받아 문자 하나하나를 배열에 넣고,
    검색할 문자가 문자열에 몇 개 들어가 있는지 개수와 몇 번째 인덱스에 위치하는지 인덱스를 출력하세요 → 차근차근 한 단계씩 하니 문제 처음 읽었을 때보다 쉽게 해결할 수 있었음
  2. 사용자가 배열의 길이를 직접 입력하여 그 값만큼 정수형 배열을 선언 및 할당하고,
    배열의 크기만큼 사용자가 직접 값을 입력하여 각각의 인덱스에 값을 초기화 하세요.
    그리고 배열 전체 값을 나열하고 각 인덱스에 저장된 값들의 합을 출력하세요 → 차근차근 한 단계씩 하니 문제 처음 읽었을 때보다 쉽게 해결할 수 있었음
  3. 사용자가 입력한 값이 배열에 있는지 검색하여,
    있으면 “OOO 치킨 배달 가능“, 없으면 “OOO 치킨은 없는 메뉴입니다“를 출력하세요.
    단, 치킨 메뉴가 들어가있는 배열은 본인 스스로 정하세요 → 중간에 조금 헷갈렸다.. 처음에 간단히 생각하고 풀었을 때 반복문 돌 때마다 출력 문구도 반복해서 출력되어 놀랐고, 1,2번 문제보다 조금 더 고민해서 해결책을 찾았다.
  4. 사용자가 입력한 높이의 별 찍기 → 인터넷에서 본 다른 별찍기 문제들보다 간단한 편이었지만, 아직 익숙하지 않아서인지 제어변수들 조건이 바로 안 떠오른다. 스스로 별찍기를 못한다는 생각 때문인지 집착이 되어서 다른 몇 개도 그려보았는데, 풀이과정이 똑똑하지 못하고 코드가 너무 지저분한 것 같다.

Part2) 클래스 = 나만의 클래스 3개 만들고, 클래스마다 객체 2개 이상씩 생성 = Monitor, Speaker, Tree → 현실의 사물들을 프로그래밍하는 것이 객체지향프로그래밍이라고는 하지만, 클래스로 만들기 적당한 대상(적당한 수의, 명확한 멤버변수들을 만들 수 있고, 내가 적당한 수의 기능을 구현할 수 있는)에 대해 고민을 조금 했다. 대상들을 선정한 후에 속성과 기능을 정리해서 작성해 보는 것은 재미있었다. 다만, 더 복잡한 기능을 구현하지 못하는 스스로가 조금 답답했다.

  • 클래스 안의 멤버변수는 최소 3개 이상 + 클래스 안의 메소드는 최소 2개 이상
  • 메소드 호출해서 객체 상태 변경 + 잘 작동하는지 확인