Coding History

국비 지원 IT(웹앱개발) 취업반 강의 5일차

BlackBirdIT 2024. 6. 3. 18:13

주말에는 약속한 것을 하지 못했다. 퇴직 후 처음 쉬는거라 정말 아무것도 하고 싶지 않아서 그냥 쉬었다..

잡소리는 치우고 오늘 배운 것에 대해 정리해보겠다. 오늘은 객체란 무엇인가에 대한 것과 함께 클래스의 개념을 배우고 2차원 배열을 배우면서 문제를 풀었다.

객체(class)

객체를 완벽하게, 지금은 이해하지는 못했다. 고 생각한다. 강사님이 설명하실 때 어떻게 보면 철학적인 영역까지 뻗칠 수 있는 아주 재미난 녀석이다. 하지만 우리는 프로그래밍을 배우고 있고 프로그래밍에서의 객체란 무엇인가를 알아야한다.

  • 객체란 무엇인가?
    객체지향언어. 말 그대로 객체를 지향하는 언어라는 말이다. 여기서 문제가 바로 객체라는 것인데, 객체가 도대체 뭘까? 객체란 무엇인가 를 참고하여 설명하자면 프로그램에서의 객체는 어떠한 상태나 어떠한 동작을 의미한다. 솔직히 철학적인 의미의 객체를 생각하는 것은 아주 재밌지만 프로그래밍적인 객체를 이해하기란 나에게 쉽지 않았다. 강사님은 공부하는 시간이 쌓여가다 보면 언젠가 갑자기 깨닫게 되는 날이 온다고 하셨다.
    일단 우리는 코드를 배우고 있기 때문에 객체를 코드로 한번 들여다보자.
// 객체를 사용하지 않았을 때, 
int person1_0 = 1; // 사람 1의 번호 
int person1_1 = 20; // 사람 1의 나이 
int person1_2 = 170; // 사람 1의 키`

int person2\_0 = 2; // 사람 2의 번호  
int person2\_1 = 30; // 사람 2의 나이  
int person2\_2 = 180; // 사람 2의 키

//객체를 사용했을 때,  
int\[\] person1 = new int\[3\]; // 객체, 인스턴스가 생긴다.  
person1\[0\] = 1; // 사람 1의 번호, 인스턴스 변수  
person1\[1\] = 20; // 사람 1의 나이, 인스턴스 변수  
person1\[2\] = 170; // 사람 1의 키, 인스턴스 변수

int\[\] person2 = new int\[3\]; // 객체, 인스턴스가 생긴다.  
person2\[0\] = 2; // 사람 2의 번호, 인스턴스 변수  
person2\[1\] = 30; // 사람 2의 나이, 인스턴스 변수  
person2\[2\] = 180; // 사람 2의 키, 인스턴스 변수

이렇게 보면 '배열'과 매우 흡사한 형태를 갖추고 있다.

그렇게 객체를 배우고 푼 문제가 아래 문제이다.

// 1. arr1 변수에 [true, fasle, true] 연결
// 2. arr2 변수에 [3.14, 7.77, 11.11] 연결
// 3. arr3 변수에 [1~10] 연결
// - 객체 안에 데이터 넣기
// - 해당 객체가 가지고 있는 데이터 전부 출력
// - 3번은 반복문 사용
// - 자바 기본 타입

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

        boolean[] arr1 = new boolean[3];
        arr1[0] = true;
        arr1[1] = false;
        arr1[2] = true;
        System.out.printf("%s " + "%s " + "%s \n", arr1[0], arr1[1], arr1[2]);

        double[] arr2 = new double[3];
        arr2[0] = 3.14;
        arr2[1] = 7.77;
        arr2[2] = 11.11;
        System.out.printf("%g " + "%g " + "%g \n", arr2[0], arr2[1], arr2[2]);

        int[] arr3 = new int[10];

        for (int i = 0; i < arr3.length; i++) { // .length: 객체의 길이
            arr3[i] = i + 1;
            System.out.printf("%d \n", arr3[i]);
        }
    }
}

객체 안에 내가 원하는 데이터를 넣고 객체가 가지고 있는 데이터를 출력시켜보았다.

객체 == 인스턴스 == 폴더
클래스 == 인스턴스 설계도 == 객체 설계도 ==폴더 설계도 == 설계도
객체안에 있는 변수처럼 동작하는 공간 == 인스턴스 변수

지역변수의 죽음 => 함수가 끝날 때
인스턴스 변수 죽음 => 인스턴스가 끝(해제)날 때,(stack에서 관찰되지 않을 때)
이런 매커니즘을 갖고 작동한다. 글로 작성한 것 보다 코드쪽이 더 이해가 쉬우니 예시 코드를 보면,

class Main {
    public static void main(String[] args) {
//        int[] 철수0 = new int[3]; -> 다양한 타입을 담을 수 없다. (기존에 있는 타입(ex, int)을 활용해서 힙에 인스턴스가 자동 생성됨.
//        철수0[0] = 12;
//        철수0[1] = 13;

        person a = new person(); // -> 기본타입이 아니라 설계도(class)를 만들어줘야 작동함.
        a.name = "김철수"; // -> 인스턴스가 존재하지 않으면 오류, 클래스 안에 객체를 생성해야함.
        a.age = 23;
        a.marry = false;
    }
}

class person{      // -> 설계도(class) 생성.
    String name;   // -> 인스턴스(객체) 생성.
    int age;       // -> 인스턴스(객체) 생성.
    boolean marry; // -> 인스턴스(객체) 생성.
}

이렇게 객체(class)를 활용해서 조금 더 큰 자유도를 우리는 얻을 수 있다.

객체의 개념을 배우고 난 뒤 이런 문제를 풀었다.

  1. 다양한 타입으로 구성되어있는 myObject 객체를 만들고 임의의 값(데이터)를 넣은 후 객체 내부의 데이터(인스턴스 변수)의 값들을 전부 출력하기

그래서 나는 예전에 내가 속해있던 밴드 멤버를 데이터로 사용해서 새로운 클래스를 만들고 출력까지 해 보았다.

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

        bandMember v = new bandMember();

        v.name = "최모씨";
        v.position = "Vocal";
        v.age = 25;
        v.isMarred = false;

        bandMember p = new bandMember();
        bm[1] = p;
        p.name = "김모씨";
        p.position = "Piano";
        p.age = 25;
        p.isMarred = false;

        bandMember g = new bandMember();
        g.name = "유모씨";
        g.position = "Guitar";
        g.age = 27;
        g.isMarred = false;

        bandMember b = new bandMember();
        b.name = "한모씨";
        b.position = "Bass";
        b.age = 28;
        b.isMarred = false;

        bandMember d = new bandMember();
        d.name = "오모씨";
        d.position = "Drum";
        d.age = 29;
        d.isMarred = false;

        System.out.printf("이름: %s\n파트: %s\n나이: %d\n결혼여부: %b\n\n", v.name, v.position, v.age, v.isMarred);
        System.out.printf("이름: %s\n파트: %s\n나이: %d\n결혼여부: %b\n\n", p.name, p.position, p.age, p.isMarred);
        System.out.printf("이름: %s\n파트: %s\n나이: %d\n결혼여부: %b\n\n", g.name, g.position, g.age, g.isMarred);
        System.out.printf("이름: %s\n파트: %s\n나이: %d\n결혼여부: %b\n\n", b.name, b.position, b.age, b.isMarred);
        System.out.printf("이름: %s\n파트: %s\n나이: %d\n결혼여부: %b\n\n", d.name, d.position, d.age, d.isMarred);
    } //-> (출력문에서 반복되는 것을 발견하고 반복문을 활용해 보려고 했다.)
}

class bandMember { // -> 객체 bandMember 선언.
    String name;
    String position;
    int age;
    boolean isMarred;
}

//출력.
//이름: 최모씨
//파트: Vocal
//나이: 25
//결혼여부: false
//
//이름: 김모씨
//파트: Piano
//나이: 25
//결혼여부: false
//
//이름: 유모씨
//파트: Guitar
//나이: 27
//결혼여부: false
//
//이름: 한모씨
//파트: Bass
//나이: 28
//결혼여부: false
//
//이름: 오모씨
//파트: Drum
//나이: 29
//결혼여부: false

위의 코드에서 반복되는 출력문을 보고 반복문도 활용해서 코드를 짜봤다.
어떻게 해야지 변수명을 숫자로 전환하는지 고민을 꽤 오래 했던 것 같다. 도저히 답이 나오지 않아서 강사님께 힌트를 조금 요청했고 그에 대한 답변은 배열을 활용해 보라는 말씀에 번뜩여서 이렇게 코드를 작성했다.

class Main {
    public static void main(String[] args) {
        bandMember[] bm = new bandMember[5]; //=> 반복문 활용을 위한 변수 선언 (5명이라 5개 만듦)


        bandMember v = new bandMember();
        bm[0] = v; // => bm[0] 에 v 변수 넣기.
        v.name = "최모씨"; // -> 인스턴스가 존재하지 않으면 오류, 클래스 안에 객체를 생성해야함.
        v.position = "Vocal";
        v.age = 25;
        v.isMarred = false;

        bandMember p = new bandMember();
        bm[1] = p; // => bm[1] 에 p 변수 넣기.
        p.name = "김모씨";
        p.position = "Piano";
        p.age = 25;
        p.isMarred = false;

        bandMember g = new bandMember();
        bm[2] = g; // => bm[2] 에 g 변수 넣기.
        g.name = "유모씨";
        g.position = "Guitar";
        g.age = 27;
        g.isMarred = false;

        bandMember b = new bandMember();
        bm[3] = b; // => bm[3] 에 b 변수 넣기.
        b.name = "한모씨";
        b.position = "Bass";
        b.age = 28;
        b.isMarred = false;

        bandMember d = new bandMember();
        bm[4] = d; // => bm[4] 에 d 변수 넣기.
        d.name = "오모씨";
        d.position = "Drum";
        d.age = 29;
        d.isMarred = false;

        for (int i = 0; i <= 4; i++) { //-> 1~5번 배열 반복 설정
            bandMember a = bm[i]; // -> 반복할 때 마다 a 값 0~4까지.
            System.out.printf("이름: %s\n파트: %s\n나이: %d\n결혼여부: %b\n\n", a.name, a.position, a.age, a.isMarred);//-> a변수를 출력문에 대입.
        }

    }
}

class bandMember {
    String name;
    String position;
    int age;
    boolean isMarred;
}

이렇게 풀어냈다. 도움을 받긴했지만 내심 되게 뿌듯한 감정을 느꼈고 이런 맛에 코딩을 하는구나 새삼 느꼈다. (앞으로 열심히 잘 할 수 있을 것 같다.

객체를 배우면서 중간에 2차원 배열에 대해서도 배웠다.

2차원배열

1차원은 무엇인가? 선이다. 그럼 2차원은? 면이다. 우리가 쓸 데이터를 2차원의 형태로 배열시키는게 바로 2차원 배열이다. 차원 개념이 들어와서 정말 재밌게 들었다.

우리가 지역변수로 선언하는 변수가 바로 점이고, 배열로 1차원인 선, 2차원인 면을 만들 수 있다.

글로 보면 헷갈리니까 예시 코드를 살펴보자.

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

        int a = 10; // 점

        int[] arr = new int[6]; // 선 1차원

        arr[0] = 1; // int[]의 첫번째 공간

        int[][] arr2 = new int[2][3]; // 면 2차원 [2] * [3] : 세개씩 두묶음

        arr2[0][0] = 1; // int[][]의 첫번째 공간
        arr2[0][1] = 2;
        arr2[1][2] = 1;

        System.out.println(arr2[1][2]);
    }
}

이런 개념인 것이다. 이걸 배우고 쉬는 시간에 2차원 배열 기초문제도 하나 풀어보았다.

코드업 1096 : [기초-2차원배열] 바둑판에 흰 돌 놓기


import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        int n, i, j, x, y;

        int[][] a = new int[20][20];

        Scanner sc = new Scanner(System.in);

        n = sc.nextInt();

        for (i=1; i<=n; i++) {
            x = sc.nextInt();
            y = sc.nextInt();
            a[x][y]=1;
        }

        for(i=1; i<=19; i++) { //한 줄(위에서 아래로) 씩
            for(j=1; j<=19; j++) //한 열(왼쪽에서 오른쪽으로) 씩
            {

                System.out.printf("%d ", a[i][j]); //값 출력

            }

            System.out.print("\n"); //줄 바꾸기
        }
    }
}

2차원 배열, 더 나아가서 3차원 배열도 있다고 하는데 나중에 배우지 않을까 싶다.

객체(class)의 구성요소

다음은 클래스의 구성요소에 대해서 배웠다.

객체(class) 구성요소.
속성 (상태, 단순데이터) - field (변수) -> 명사
기능 (행동, 실행데이터) - method (함수) -> 동사

이렇게 속성과 기능으로 나뉘게 되는데 속성은 명사, 즉 무언가 이름을 정해주는 역할이고 기능은 무언가를 입력 받거나 출력하거나 하는 실행(ex, .exe파일) 을 생각하면 쉽게 이해할 수 있었다.

바로 방금전 위의 코드에서

        Scanner sc = new Scanner(System.in);

이건 기능의 역할을 한다는 것이다.

그래서 아까 위의 객체의 개념, 그리고 구성요소를 취합해서 푼 문제가 바로 이 문제이다.
원래는 순차적으로 객체 선언부터 변수 선언, 변수 입력, 등등 문제를 풀었지만 최종형태만 다뤄보도록 하겠다.

// 문제 : 번호가 다른 각각의 자동차가 서로 다른 최고속력으로 달리게 해주세요.

class Main { // main 클래스
    public static void main(String[] args) {

        // 구현시작
        car aCar = new car(); // -> aCar 선언
        car bCar = new car(); // -> bCar 선언

        aCar.maxKm = 230; // -> aCar 최고 속력 데이터 저장
        bCar.maxKm = 210; // -> bCar 최고 속력 데이터 저장

        aCar.drive(); // -> 메서드 호출 (함수 실행) -> 구성요소중 기능을 담당

        bCar.drive(); // -> 메서드 호출 (함수 실행)
    }
}

class car {
    int maxKm;

    void drive() { // -> 실행버튼(기능) -> 메서드 -> 기능을 담당
        System.out.printf("자동차가 최고속력 %dkm로 달립니다.\n", maxKm);
    }
}

이렇게 작성된 코드를 보면 두개의 크래스로 나누어져 있고, main클래스에 데이터를 입력하고 car클래스에 변수 타입을 정했다. car클래스 안에 void는 메서드로 drive라는 기능을 담당하고 있다. aCar.drive(); 라는 버튼을 메인클래스에서 누름으로써 다른 객체(CarClass)에 있는 메서드를 호출하고 실행하는 식으로 작동된다.

오늘 배운 것은 이렇게 해서 java의 객체지향언어가 정확히 무엇인지 톺아보는 시간을 가졌다.

내일도 화이팅!!