day-5 (23.05.08)

정길규·2023년 5월 8일

Part 05 객체지향1

클래스와 객체

클래스의 정의 : 클래스란 객체를 정의해 놓은 것.
클래스의 용도 : 클래스는 객체를 생성하는데 사용.

객체의 정의 : 실제로 존재하는 것!, 사물 또는 개념
객체의 용도 : 객체가 가지고 있는 속성과 기능에 따라 다름.

객체 = 속성(변수) + 기능(메서드) (총갯수가 : 맴버 수)

객체의 생성 및 사용

class Tv1_1 {
    // 속성 : 변수 선언
    String color; // 색깔
    boolean power = false; // 전원상태 : false 로 초기화
    int channel = 1; // 체널 : 1 로 초기화

    // 기능 : 메서드 선언
    void power() { // 전원 기능
        power = !power;
        if (power) {
            System.out.println("전원 ON");
        } else {
            System.out.println("전원 OFF");
        }
    }

    void channelUp() {
        channel++;
        System.out.println("체널 증가");
    }

    void channelDown() {
        channel--;
        System.out.println("체널 감소");
    }
}

class Tv1_1Main {
    public static void main(String[] args) {
        Tv1_1 t1 = new Tv1_1(); // Tv1 인스턴스
        t1.color = "검정색"; // 색깔 초기화
        Tv1_1 t2 = new Tv1_1(); // Tv2 인스턴스
        t2.color = "흰색"; // 색깔 초기화

        System.out.println("Tv1 인스턴스 색깔 = " + t1.color);
        System.out.println("Tv2 인스턴스 색깔 = " + t2.color);

        t1.power(); // 메서드 호출
        System.out.println("Tv1 인스턴스 채널 = " + t1.channel);

        t1.channelUp(); // 메서드 호출
        System.out.println("Tv1 인스턴스 채널 : " + t1.channel);
        t1.channelDown(); // 메서드 호출
        System.out.println("Tv1 인스턴스 채널 : " + t1.channel);

        t1.power(); // 메서드 호출

        // Tv2 인스턴스 참조변수에 Tv1 인스턴스의 주소 저장 했을 때
        t2 = t1;

        System.out.println("Tv1 인스턴스 색깔 = " + t1.color); // 검정색
        System.out.println("Tv2 인스턴스 색꺌 = " + t2.color); // 검정색

        // 흰색이었던 Tv2 인스턴스 의 색깔이 검정색으로 바뀐건가요?
        // 아닙니다.
        // 참조변수 t2 에 저장되어있던 Tv2 인스턴스 의 주소가 없어지고
        // Tv1 의 주소가 t2 참조변수에 저장이 됩니다.

        // 따라서 t2 = t1; 이후 부터는
        // t2 참조변수로는 더 이상 Tv2 인스턴스 에 접근할 수 없습니다.
    }
}

객체 배열

객체 배열 == 참조변수 배열
여러 개의 객체를 담을 수 있는 배열

  • Tv[] tvArr = new Tv[3];
class Tv1_2 {
    // 속성 : 변수 선언
    String color; // 색깔
    boolean power = false; // 전원상태 : false 로 초기화
    int channel = 1; // 체널 : 1 로 초기화
    // 브랜드 이름 속성 추가
    String brand;

    // 기능 : 메서드 선언
    void power() { // 전원 기능
        power = !power;
        if (power) {
            System.out.println("전원 ON");
        } else {
            System.out.println("전원 OFF");
        }
    }

    void channelUp() { // 체널 증가
        channel++;
        System.out.println("체널 증가");
    }

    void channelDown() { // 체널 감소
        channel--;
        System.out.println("체널 감소");
    }
}

class Tv1_2Main {
    public static void main(String[] args) {
        Tv1_2[] tvArr = new Tv1_2[3];

        tvArr[0] = new Tv1_2();
        tvArr[1] = new Tv1_2();
        tvArr[2] = new Tv1_2();

        tvArr[0].color = "보라색";
        tvArr[1].color = "주황색";
        tvArr[2].color = "핑크색";

        for (int i = 0; i < tvArr.length; i++) {
            System.out.println(i + 1 + "번째 Tv인스턴스 색깔 : " + tvArr[i].color);
        }

        for (int i = 0; i < tvArr.length; i++) {
            System.out.println(i + 1 + "번째 Tv인스턴스");
            tvArr[i].power();
        }

        System.out.println();
        // 브랜드명 추가 전 확인
        for (int i = 0; i < tvArr.length; i++) {
            System.out.println(i + 1 + "번째 Tv인스턴스의 브랜드 명 : ");
            System.out.println(tvArr[i].brand);
        }
        System.out.println();

        // 새로운 참조변수에 배열 안에 들어있는 객체 주소 값 배정
//        Tv1_2 samsung = tvArr[0];
//        Tv1_2 lg = tvArr[1];
//        Tv1_2 apple = tvArr[2];
//
//        // 참조변수를 사용해서 배열안에 넣어준 객체에 접근해서 각 인스턴스에 브랜드 이름 추가하기
//
//        samsung.brand = "samsung";
//        lg.brand = "lg";
//        apple.brand = "apple";

        tvArr[0].brand = "samsung";
        tvArr[1].brand = "lg";
        tvArr[2].brand = "apple";


        for (int i = 0; i < tvArr.length; i++) {
            System.out.println(i + 1 + "번째 Tv인스턴스의 브랜드 명 : ");
            System.out.println(tvArr[i].brand);
        }
    }
}

클래스의 정의

클래스 == 데이터 + 함수
클래스 == 사용자 정의 타입

  • 클래스를 사용하지 않고 관리
class NoneClassTime {
    public static void main(String[] args) {
        // 총 3명 의 시간을 변수로 관리
        int hour1, hour2, hour3;
        int minute1, minute2, minute3;
        int second1, second2, second3;

        // 총 3명 의 시간을 배열로 관리
        int[] hour = new int[3];
        int[] minute = new int[3];
        int[] second = new int[3];
    }
}
  • 클래스로 만들어서 관리
class Time3_1 {
    int hour;
    int minute;
    int second;
}

class Time3_1Main {
    public static void main(String[] args) {
        // 총 3명 의 시간을 객체로 관리
        Time3_1 t1 = new Time3_1();
        Time3_1 t2 = new Time3_1();
        Time3_1 t3 = new Time3_1();

        // 총 3명 의 시간을 객체 배열로 관리
        Time3_1[] timeArr = new Time3_1[3];
        timeArr[0] = new Time3_1();
        timeArr[1] = new Time3_1();
        timeArr[2] = new Time3_1();
    }
}

변수의 종류

클래스 영역 : 클래스 변수

  • 클래스가 메모리에 올라갈 때 생성.
  • 객체 생성을 하지 않아도 생성되고 언제든지 사용 가능.
  • 접근방법 : 클래스명.클래스변수명

클래스 영역 : 인스턴스 변수

  • 객체가 생성될 때 인스턴스 변수가 생성.
  • 접근 방법 : 참조변수명.인스턴스변수명.

메서드 영역 : 지역 변수

  • 메서드가 호출 되서 실행될 때 생성.
  • 메서드가 종료되면 자동으로 제거.
class Obj4_1 {
    int iv;  // 인스턴스 변수
    static int cv;  // 클래스 변수(static 변수, 공유 변수)
    
    void method() {
        int lv;
        lv = 30;
        // 지역변수는 자동으로 초기화가 되지 않기 때문에 사용하려면 반드시 초기화 필요
        System.out.println("lv 지역 변수 = " + lv);
    }
}

class Obj4_1Main {
    public static void main(String[] args) {
        
        // 클래스 변수 접근 및 사용
        // 접근방법 : 클래스명.클래스변수이름
        Obj4_1.cv = 10;
        System.out.println("ObjVar.cv 클래스 변수 = " + Obj4_1.cv);
        
        // 인스턴스 변수 생성 및 사용
        // Obj4_1.iv = 20;  // Error, 인스턴스를 통해서만 생성 및 사용 가능
        Obj4_1 objVar = new Obj4_1();
        objVar.iv = 20;
        System.out.println("objVar.iv 인스턴스 변수 = " + objVar.iv);
        
        // 지역 변수 생성 및 사용
        // objVar.lv // Error, 인스턴스로 지역 변수 바로 접근 불가능
        objVar.method(); // 메서드 호출 시 지역 변수 생성
        // 메서드 종료시 지역 변수 삭제
    }
}

메서드

반환타입 메서드 이름(타입 변수명, 타입 변수명, ...) {  // (선언부)
            // 메서드가 호출되면 수행할 코드 (구현부)
}

메서드의 장점과 작성

장점
1. 중복 코드 제거
2. 관리 용이
3. 재사용 가능
작성
1. 반복적으로 수행되는 여러 문장을 메서드로 작성.
2. 하나의 메서드는 한 가지 기능만 수행 하도록 작성.

메서드 호출

메서드이름(값1, 값2, ...)

class Method5_1 {
    int add(int x, int y) {
        int result = x + y;
        return result; // 값을 반환
    }
}

class Method5_1Main {
    public static void main(String[] args) {
        Method5_1 method = new Method5_1();  // Method5_1 클래스에 만든 메섣 add 를 사용 하기 위해 객체 생성

        int result = method.add(3, 5);  // add 메서드를 사용해서 입력한 값(3, 5)으로 처리된 값을 반환받아 result 변수에 저장
        System.out.println("result = " + result);
    }
}

return

실행 중인 메서드를 종료하고 호출한 곳으로 되돌아 감.

  • 반환타입이 void가 아닌 경우, 반ㄷ시 return 문이 필요.
  • void 는 컴파일러가 자동으로 메서드 마지막에 return; 을 추가.
class Method5_2 {
    void gugudan(int dan) {
        if (!(dan >= 2 && dan <=9)) {
            System.out.println(dan + "단은 없습니다.");
            return;
        }
        System.out.println(dan + "단 시작!");
        for (int i = 1; i < 10; i++) {
            System.out.println(dan + "*" + i + " = " + dan + i);
        }
        System.out.println();
    }
    boolean checkMax(int x, int y) {
        if (x > y) {
            return true;
        } else {
            return false;
            // return 반드시 필요 합니다. 만약 없으면 조건문이 false 일 경우, void가 아닌데 return 문이 없으므로 Error
        }
    }
}

class Method5_2Main {
    public static void main(String[] args) {
        Method5_2 method = new Method5_2();

        method.gugudan(2);
        method.gugudan(5);
        method.gugudan(10);
        method.gugudan(9);

        System.out.println("method.checkMax(10, 8) = " + method.checkMax(10, 8));
        System.out.println("method.checkMax(5, 9) = " + method.checkMax(5, 9));
    }
}

문장들의 묶음

코드의 중복을 하나의 묶음으로 만들어 코드의 가독성 및 효율을 높여줍니다.

class Method5_3 {
    static void initObj(Time3_1 time, int hour, int minute, int second) {
        time.hour = hour;
        time.minute = minute;
        time.second = second;
    }
}

class Method5_3Main {
    public static void main(String[] args) {
        Time3_1 t1 = new Time3_1();
        t1.hour = 100;
        t1.minute = 40;
        t1. second = 43;

        Time3_1 t2 = new Time3_1();
        t2.hour = 22;
        t2.minute = 30;
        t2.second = 23;

        Time3_1 t3 = new Time3_1();
        t3.hour = 45;
        t3.minute = 40;
        t3.second = 52;

        System.out.println("t1.hour = " + t1.hour);
        System.out.println("t2.hour = " + t2.hour);
        System.out.println("t3.hour = " + t3.hour);
        System.out.println();

        // 하나하나 인스턴스를 만들고 위처럼 인스턴스 변수를 초기화 하려니 매위 귀찮지 않나요?
        // 물론 '생성자' 라는 개념이 뒤에 나오지만 일단은 메서드를 사용하여 코드이 수를 확 줄여 보겠습니다.

        Time3_1 t4 = new Time3_1();
        Time3_1 t5 = new Time3_1();
        Time3_1 t6 = new Time3_1();

        Method5_3.initObj(t4, 100, 20, 43);
        Method5_3.initObj(t5, 22, 30, 23);
        Method5_3.initObj(t6, 45, 40, 52);

        System.out.println("t4.hour = " + t4.hour);
        System.out.println("t5.hour = " + t5.hour);
        System.out.println("t6.hour = " + t6.hour);

        // 이처럼 메서드를 사용하니 코드의 수가 굉장히 많이 줄어 가독성이 좋아졌습니다.
    }
}

호출 스택

메서드 수행에 필요한 메모리가 제공되는 공간
메서드가 호출되면 호출 스택에 메모리가 할당, 종료되면 헤제됨.
스택(stack) : 밑이 막힌 상자. 위에 차곡차곡 쌓인다.

class CallStack5_1 {

    static void firstMethod() {
        System.out.println("fistMethod()");
        secondMethod();
    }

    static void secondMethod() {
        System.out.println("secondMethod()");
        thirdMethod();
    }

    static void thirdMethod() {
        System.out.println("thirdMethod()");
        finalMethod();
    }

    static void finalMethod() {
        System.out.println("finalMethod()");
    }

    public static void main(String[] args) {
        firstMethod();
    }
}
class CallStack5_2 {
    static void firstMethod() {
        secondMethod();
        System.out.println("fistMethod()");
    }

    static void secondMethod() {
        thirdMethod();
        System.out.println("secondMethod()");
    }

    static void thirdMethod() {
        finalMethod();
        System.out.println("thirdMethod()");
    }

    static void finalMethod() {
        System.out.println("finalMethod()");
    }

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

5일차 학습을 마치며

오늘은 객체지향에 대해 공부를 하였다. 오늘 학습한 내용을 전부 머리에 넣을수 있을지 모르겠다. 아마 파트는 반복해서 학습을 해야 될것 같다. 현재는 그냥 느낌으로만 아는 정도 인것 같다.

0개의 댓글