[자바] 김영한의 실전자바 - 기본편 정리(1)

곽동현·2024년 3월 12일
0

[ 섹션 1 : 클래스 ]

클래스가 왜 필요할까요?

클래스는 설계도 이다.
클래스(설계도)를 사용해서 실제 메모리에 만들어진 실체를 객체,인스턴스라고 한다.

클래스와 메모리할당

    //선언한 순간 Student는 메모리에 올라간다(X). 메모리에 올라가지는 않고, 인스턴스가 생성되면 메모리에 올라간다.(O)
    //클래스(설계도)를 사용해서 실제 메모리에 만들어진 실체를 객체,인스턴스라고 한다.
    // Student = 설계도 : 그저, 하나의 파일이라고 생각? : (붕어빵틀)
    Student student1;   // 객체생성은 아님. car라는 참조 변수가 메모리 영역 stack이라는 영역에 만들어지는 단계
    student1 = new Student();   // 실체 : 메모리에 올라온 객체 (팥붕 하이)
                                // new 연산자를 통해 메모리 내에 공간을 할당받고, 메모리 주소값(참조값)을 반환한다. -> 생성된 객체를 참조할 수 있는 참조값을 car에 담는다.
                                // 메모리를 할당 받는다는 것은 heap 영역에 저장된다는 것이다.
                                // heap영역은 생성된 객체들이 GC에 의해 자동 소멸되어지는 공간이다.

new 연산자

new 연산자는 객체를 Heap이라는 메모리 영역에 메모리 공간을 할당해주고 메모리주소를 반환한 후 생성자를 실행시켜준다

[참고] https://yoo11052.tistory.com/52

클래스 내부에 정의한 변수들을 무엇이라고 칭하나요?

멤버변수, 혹은 필드라고 칭한다.
클래스에 소속된 변수를 뜻한다.

자바의 = 연산(대입)은 항상 값을 복사한다는 점을 기억하자!

        Student student1 = new Student();   //x001
        student1.name = "학생1";
        student1.age = 15;
        student1.grade = 90;

        Student student2 = new Student();   //x002
        student2.name = "학생2";
        student2.age = 16;
        student2.grade = 80;

        Student[] students = new Student[2];    //x005
        // ✔ 자바에서 대입은 항상 변수에 들어 있는 값을 복사한다!
        // 각 student 변수에는 뭐가 들어있었을까? ("값"이 아닌 "주솟값"을 복사한다는 점을 생각해보자!)
        students[0] = student1;         //x005[x001][x002] 라고 생각
        students[1] = student2;

        students[0].name="해킹";
        System.out.println(student1.name); // 출력 값 : 해킹

[ 섹션 2 : 기본형과 참조형 ]

자바의 대입은 항상 값을 복사한다는 점을 기억하자! (반복)

기본형과 참조형의 차이는?

  • 기본형(Primitive Type): int , long , double ,boolean 처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형이라 한다.
  • 참조형(Reference Type): Student student1 , int[] students 와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형이라 한다. 참조형은 객체 또는 배열에 사용된다.

기본형과 참조형 대입 코드로 이해하기

기본형 대입

int a = 10;
int b = a;

-> 리터럴 값이 복사되어 a가 변경되어도 b에는 영향이 없다. (다른 건물)

참조형 대입

Student s1 = new Student();
Student s2 = s1;

-> 주소 값이 복사되어 a가 변경되면 b도 변경된다. (같은 건물)

GC(Garbage Collection) 이란?

  • JAVA는 JVM 위에서 GC의 기능을 제공한다.
  • heap 영역에서 아무것도 참조하지 않는 인스턴스는 GC(Garbage Collection) 기능으로 메모리에서 삭제된다.
  • C언어는 GC의 기능이 없어서, 직접 해제 해주어야 한다.
        Data data = null;
        System.out.println(data);
        data = new Data();
        System.out.println(data);
        data = null;    // GC의 효과 발생 ! 앞선 Data 인스턴스를 참조하는게 아무것도 없음
        System.out.println(data);

[ 섹션 3 : 객체지향프로그래밍 ]

절차 지향 프로그래밍 VS 객체 지향 프로그래밍

절차 지향 프로그래밍

  • 절차. 즉 실행 순서를 지향한다. ("어떻게"를 중심으로 해결할 지 프로그래밍)
  • 하나의 흐름대로 처리하는 방식

객체 지향 프로그래밍

  • 객체. 즉 어떠한 사물이나 사건을 지향한다. ("무엇을"중심으로 해결할 지 프로그래밍)
  • 객체를 중심으로 바라보다보니 서로간의 상호작용을 중요시 함.

가장 큰 차이

  • 데이터 처리 방식 : 변수(데이터)와 기능(함수)를 분리하는지 여부이다.
    -> 절차지향 : 데이터와 기능을 분리시켜 사용한다.
    -> 객체지향 : 객체 안에 기능을 포함해서 사용한다.

🔍메서드는 객체를 생성해야 호출 할 수 있다.

그러나 static이 붙으면 객체를 생성하지 않고도 메서드를 호출 할 수 있다.

캡슐화란?

속성과 기능을 하나로 묶어서 필요한 기능을 메서드를 통해 외부에 제공하는 것

        MusicPlayer player = new MusicPlayer();
        //음악 플레이어 켜기
        player.on();
        //볼륨 증가
        player.volumeUp();
        //볼륨 증가
        player.volumeUp();
        //볼륨 감소
        player.volumeDown();
        //음악 플레이어 상태
        player.showStatus();
        //음악 플레이어 끄기
        player.off();

[ 섹션 4 : 생성자 ]

생성자의 필요성

MemberInit 클래스

public class MemberInit {
    String name;
    int age;
    int grade;
}

절차지향 코드1 (모듈화 X)

다음은 절차지향에서 사용했던 생성자이다.

public static void main(String[] args) {
        MemberInit member1 = new MemberInit();
        member1.name = "user1";
        member1.age = 15;
        member1.grade = 90;

        MemberInit member2 = new MemberInit();
        member2.name = "user2";
        member2.age = 16;
        member2.grade = 80;

        MemberInit[] members = {member1,member2};
        }
    }

절차지향 코드2 (모듈화 O)

위 과정에서 메서드를 추출한 방법이다. 여전히 모듈화를 사용했으나, 객체지향적이지는 못하다.

        MemberInit member1 = new MemberInit();
        initMemeber(member1, "user1", 15,90);

        MemberInit member2 = new MemberInit();
        initMemeber(member2, "user2", 16,80);

        MemberInit[] members = {member1,member2};
        }
    }
    static void initMemeber(MemberInit member, String name, int age, int grade){
        member.name = name;
        member.age = age;
        member.grade = grade;
    }

클래스 내에 메서드 넣기

클래스 내에 메서드를 넣어줌으로서 객체지향적인 코드가 완성되었다!

public class MemberInit {
    String name;
    int age;
    int grade;

    //this : 자기 자신(인스턴스)의 참조값을 가리킨다 x001.name
    //같은 변수이름이면 코드블럭의 우선순위는 매개변수가 갖게 된다.
    void initMember(String name, int age, int grade){
        this.name = name;
        this.age = age;
        this.grade = grade;
    }
}

객체지향 코드1

        MemberInit member1 = new MemberInit();
        member1.initMember("user1", 15,90);

        MemberInit member2 = new MemberInit();
        member2.initMember("user2", 16,80);

        MemberInit[] members = {member1,member2};

생성자

프로그래밍을 하다보면 객체를 생성하고 그 즉시 초기값을 할당해야 하는 경우가 많다.
따라서 객체 지향 언어는 객체를 생성 하자마자 즉시 필요한 "기능"을 수행할 수 있도록 생성자라는 기능을 제공한다.

생성자는 메서드와 비슷하지만 다음과 같은 차이가 있다.

  • 생성자의 이름은 클래스 이름과 같아야 한다. 따라서 첫 글자도 대문자로 시작!
  • 생성자는 반환 타입이 없다 !
  • 그 외에는 메서드와 같은 기능을 한다.

생성자가 하나도 없으면?

생성자가 하나도 없으면 자바 컴파일러매개변수도, 어떠한 기능도 없는 기본 생성자를 자동으로 만들어준다.

but 생성자가 하나라도 있으면 기본 생성자를 만들지 않는다.

생성자의 가장 큰 장점

생성자를 정의했다면, 정의한 생성자를 "반드시" 호출 해야한다제약사항이 생긴다.
-> 생성자를 사용하면 필수값 입력을 보장할 수 있다.

만일 생성자를 직접 정의했는데, 호출하지 않으면 컴파일 에러가 발생한다.

📌좋은 프로그램은 무한한 자유도가 주어진 프로그램이 아니라 적절한 제약사항이 주어진 프로그램이다

생성자 오버로딩

아래와 같이 생성자도 매개변수에 따라 오버로딩이 가능하다!

public class MemberConstruct {
    String name;
    int age;
    int grade;

    MemberConstruct(String name, int age, int grade){
        System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade);
        this.name = name;
        this.age = age;
        this.grade = grade;
    }

    MemberConstruct(String name, int age){
        this.name = name;
        this.age = age;
        this.grade = 50;
    }

근데 여기서 this.name, this.age 와 같이 중복되는 코드를 지우고 싶으면 어떻게 해야할까?

this()

this() 기능으로 위와같은 기능을 수행할 수 있다.

  • this() 는 생성자 내부에서만 사용 가능하다.
  • this() 는 생성자 블록 첫 줄 에서만 가능하다. (아니면 컴파일 오류)
    MemberConstruct(String name, int age, int grade){
        System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" + grade);
        this.name = name;
        this.age = age;
        this.grade = grade;
    }

    MemberConstruct(String name, int age){
        this(name,age,50);  //변경 : 중복제거
//        this.name = name;
//        this.age = age;
//        this.grade = 50;
    }
profile
실패의 경험들을 채워나가기!

0개의 댓글