본문 바로가기
Java

[JAVA] Chapter 5. 객체와 클래스

by nyeoo 2023. 11. 7.

1. 객체(object)

  • 객체는 설계도화 가능하며, 속성(데이터)과 기능(동작, 행위)을 가진 존재

  • 보드마카를 쓰고, 뚜껑을 여는 행위를 통해 잉크량이 달라지듯이 메소드라는 동작, 행위로 변수가 달라진다. 같은 틀에 찍어낸 붕어빵(객체)이라도 같은 붕어빵(객체)이 아님
  • 객체 생성

  • 설계도인 클래스가 존재한다고 해서 객체가 자동으로 만들어지는 것이 아님을 주의
  • 자바는 메모리공간의 주소값에 직접 접근하는 것을 허용하지 않음. 변수를 통해 접근하도록 함
  • New => 메모리에 새롭게 퍼올려줘! 라는 의미

2. 클래스(class)

  • public이 붙어있는 클래스는 한 파일에 1개만 가능
  • 반드시 파일 이름은 public이 붙어있는 클래스의 이름으로 저장해야함
  • 한 파일에 클래스가 여러 개면 컴파일 시 여러 개의 (.class) 파일 생성됨
  • 같은 경로(디렉토리) 안에 있으면 참조(import)할 필요 없음

2-1. 클래스의 구조

class 클래스명
{
    // 멤버 변수
    // 생성자 메소드
    // 메소드
}

3. 지역변수, 인스턴스 변수, 클래스 변수

  • 지역변수 (Local variable) : 메소드 영역에서 선언되어 내부에서만 사용이 가능한 변수. 초기화 과정을 거치지 않으면 사용할 수 없음. 즉, 자바가 자동으로 초기화를 수행하지 않음
  • 인스턴스 변수 : 클래스 영역에서 선언된 변수이며, 인스턴스 변수가 생성되는 시점은 인스턴스가 생성되는 시점이며, 인스턴스롤 "통해서" (참조변수명.변수명) 접근가능하므로 인스턴스 변수라고 부름. Test(클래스명)의 멤버변수, 글로벌 변수로 불리기도 함.
  • 클래스 변수 (static 변수) : 클래스 변수가 생성되는 시점은 클래스가 로딩되는 시점. 즉, 자바가 인스턴스를 생성하기 전 설계도인 클래스를 읽어내는 시점이므로 인스턴스 생성하지 않고, 클래스명을 통해 (클래스명.변수명) 접근 가능 . 같은 클래스 내부에 있으면 클래스명 생략 가능(변수명)
    → 인스턴스 변수 또는 인스턴스 메소드는 동일한 클래스의 다른 메소드에서 바로 접근하는 것이 가능하지만 클래스 메소드에서는 접근 불가능
public class Test100
{
    static int a = 10;        //-- static 변수(클래스 변수, class 변수, 정적 변수)
    int b = 20;                //-- non-static 변수(인스턴스 변수, instance 변수)

    void write()            //-- non-static 메소드(인스턴스 메소드, instance 메소드)
    {
        System.out.println("인스턴스메소드 -> 클래스변수 a : " + a);        
        System.out.println("인스턴스메소드 -> 인스턴스변수 b : " + b);
    }

    static void print()        //-- static 메소드(클래스 메소드, class 메소드, 정적 메소드)
    {
        System.out.println("클래스메소드 -> 클래스변수 a : " + a);
        //System.out.println("클래스메소드 -> 인스턴스변수 b : " + b);
        //--==>> 에러 발생(컴파일 에러)
    }

    public static void main(String[] args)
    {
        System.out.println("main() 메소드 -> 클래스 변수 a : " + Test100.a);
        //--==>> main() 메소드 -> 클래스 변수 a : 10

        System.out.println("main() 메소드 -> 클래스 변수 a : " + a);
        //--==>> main() 메소드 -> 클래스 변수 a : 10

        Test100.print();
        //--==>> 클래스메소드 -> 클래스변수 a : 10

        print();
        //--==>> 클래스메소드 -> 클래스변수 a : 10

        //System.out.println("main() 메소드 -> 인스턴스 변수 b : " + b);
        //---==>> 에러 발생(컴파일 에러)
        //System.out.println("main() 메소드 -> 인스턴스 변수 b : " + Test100.b);
        //---==>> 에러 발생(컴파일 에러)

        //Test100.write();
        //---==>> 에러 발생(컴파일 에러)
        //write();
        //---==>> 에러 발생(컴파일 에러)

        // Test100 클래스 기반 인스턴스 생성
        Test100 ob = new Test100();

        System.out.println("main() 메소드 -> 인스턴스 변수 b : " + ob.b);
        //--==>> main() 메소드 -> 인스턴스 변수 b : 20

        //write();
        //--==>> 에러 발생(컴파일 에러)

        // 생성된 인스턴스를 통해 인스턴스 메모리에 접근(호출)
        ob.write();
        //--==>> 인스턴스메소드 -> 클래스변수 a : 10
        //         인스턴스메소드 -> 인스턴스변수 b : 20

        // 생성된 인스턴스를 통해 클래스 변수에 접근
        System.out.println("main() 메소드 -> 클래스 변수 a : " + a);
        //--==>> main() 메소드 -> 클래스 변수 a : 10

        // 생성된 인스턴스를 통해 클래스 메소드에 접근(호출)
        ob.print();
        //--==>> 클래스메소드 -> 클래스변수 a : 10
        // 이러한 형태로도 접근이 가능하지만,
        // 클래스명.변수명 그리고 클래스명.메소드명
        // 의 형태로 접근(호출)하는 것이 일반적

        System.out.println("main() 메소드 -> 클래스 변수 a : " + a);
        System.out.println("main() 메소드 -> 클래스 변수 a : " + Test100.a);
        System.out.println("main() 메소드 -> 클래스 변수 a : " + ob.a);
        //--==>> main() 메소드 -> 클래스 변수 a : 10
        //         main() 메소드 -> 클래스 변수 a : 10
        //         main() 메소드 -> 클래스 변수 a : 10


        //Test100 클래스 기반 인스턴스 생성
        Test100 ob2 = new Test100();

        ob2.a = 10000;                //-- 클래스 변수
        ob2.b = 10000;                //-- 인스턴스 변수

        System.out.println("ob2 확인-------------------------------");
        ob2.write();
        //--==>> 인스턴스메소드 -> 클래스변수 a : 10000
        //         인스턴스메소드 -> 인스턴스변수 b : 10000

        System.out.println("ob 확인-------------------------------");
        ob.write();
        //--==>> 인스턴스메소드 -> 클래스변수 a : 10000        //-- a는 공유 스테이플러
        //         인스턴스메소드 -> 인스턴스변수 b : 20            //-- b는 개인 딱풀

        }
}

4. 생성자(constructor)

  • 생성자의 역할
    1. 인스턴스 생성 → 메모리 할당
    2. 멤버변수 초기화
  • 생성자의 특징
    1. 생성자는 인스턴스 생성시 딱 한 번만 호출되는 메소드이며, 이 시점에 멤버 변수가 초기화 값을 가짐
    2. 이름 앞에 리턴 자료형을 붙이지 않음. (void도 붙이지 않음)
    3. 여러 개의 생성자 오버로딩이 가능
  • 일반 메소드와 다른 점
    1. 클래스명과 이름이 같아야 하므로 첫 글자는 대문자
    2. 한 번만 호출 가능 (인스턴스 생성시)
    3. 생성자 내에서는 final 멤버 변수의 초기화가 가능(특권)

4-1. default 생성자

  • 사용자 정의 생성자가 존재하지 않을 때, 컴파일 과정에서 자동 삽입
class NumberTest
{
    int num;

    /*                    
    NumberTest()    //-- 디폴트(default) 생성자
    {
    }
    */

    NumberTest()    //-- 사용자 정의 생성자
    {
        num = 1;
        System.out.println("사용자 정의 생성자 호출~!!!");
        //-- 인스턴스 생성만으로 출력 가능
    }
}

4-2. 생성자와 매개변수 (생성자 오버로딩)

  • this.변수명은 멤버변수를 의미. 매개변수와 동일한 변수명을 가진 멤버변수를 구분가능
public class Test077
{
    int val1;
    double val2;

    Test077()
    {
        val1=0;
        val2=0;
        System.out.println("매개변수 없는 생성자");
    }

    Test077(int val1)
    {    
        this.val1=val1;
        val2=0;
        System.out.println("int형 데이터를 넘겨받는 생성자");
    }

    Test077(double val2)
    {
        val1=0;
        this.val2=val2;
        System.out.println("double형 데이터를 넘겨받는 생성자");
    }

    Test077(int val1, double val2)
    {
        this.val1=val1;
        this.val2=val2;
        System.out.println("int형 데이터와 double형 데이터를 넘겨받는 생성자");
    }


    public static void main(String[] args)
    {
        Test077 ob1 = new Test077();
        System.out.println(ob1.val1 + ", " + ob1.val2);
        //--==>> 매개변수 없는 생성자
        //         0, 0.0

        Test077 ob2 = new Test077(4);
        System.out.println(ob2.val1 + ", " + ob2.val2);
        //--==>> int형 데이터를 넘겨받는 생성자
        //         4, 0.0

        Test077 ob3 = new Test077(7.0);
        System.out.println(ob3.val1 + ", " + ob3.val2);
        //--==>> double형 데이터를 넘겨받는 생성자
        //         0, 7.0

        Test077 ob4 = new Test077(4, 7.0);
        System.out.println(ob4.val1 + ", " + ob4.val2);
        //--==>> int형 데이터와 double형 데이터를 넘겨받는 생성자
        //         4, 7.0
    }
}

4-3. 생성자와 초기화 블럭 (Initialized Block)

  • 초기화 블럭은 생성자보다 먼저 실행되며, 이는 생성자의 우선순위가 더 높음을 의미
public class Test078
{
    // 이러한 초기화도 가능
    /*
    int n = 100;
    int m = 200;
    */

    int n;
    int m;

    // 생성자(Constructor)
    Test078()
    {
        n=100;
        m=200;
        System.out.println("생성자 실행");
    }

    // 초기화 블럭
    {
        n=10;
        m=20;
        System.out.println("초기화 블럭 실행");
    }

    // 멤버 출력 메소드
    void write()
    {
        System.out.println("n : " + n + ", m : " + m);
    }

    Test078(int n, int m)
    {
        this.n = n;
        this.m = m;
        System.out.println("매개변수 있는 생성자 실행");
    }


    public static void main(String[] args)
    {
        Test078 ob1 = new Test078();
        ob1.write();
        //--==>> 초기화 블럭 실행
        //         생성자 실행
        //         n : 100, m : 200

        Test078 ob2 = new Test078(222, 333);
        ob2.write();
        //--==>> 초기화 블럭 실행
        //         매개변수 있는 생성자 실행
        //         n : 222, m : 333
    }
}

5. 메소드

  • 메소드 정의 : 메소드명( ){ }
  • 메소드 호출 : 메소드명( );
  • 메소드의 종류
    1. 값을 반환(값을 놓고감)하는 메소드
    2. 값을 반환하지 않는 메소드
      → 값을 반환하지 않는 메소드 이름 앞에는 void를 붙임. (void = 공허함) ex) main 메소드는 아무것도 반환하지 않는 메소드

 

· 자바의 메소드 구조

리턴자료형 메소드명(입력자료형1 매개변수1, 입력자료형2 매개변수2, ...)
{
    ...    
    return 리턴값;  // 리턴자료형이 void 인 경우에는 return 문 필요없음
}

리턴 자료형메소드 수행 후 리턴되는 값의 자료형을 의미. 리턴 자료형이 필요한 이유는 메소드 밖에서는 메소드 안이 보이지 않기 때문임. 메소드는 결과값을 반환하기 위해 return이라는 키워드를 사용

5-1. 매개변수와 인자

  • 매개변수 (parameter) : 메소드가 외부에서 데이터를 받을 때 사용
  • 인자 (argument) : 메소드를 호출할 때, 매개변수에 전달되는 데이터
  • 메소드 정의시 매개변수 표현

메소드명(int a, b)--(X)
메소드명(int a, int b)--(O) 두 번째가 맞는 문법

5-2. 메소드 오버로딩 (메소드 중복정의)

  • 메소드 오버로딩이란, 메소드가 처리하는 기능은 같고, 메소드의 인수(인자, 매개변수, 파라미터)의 갯수가 다르거나, 자료형(Data Type)이 다른 경우 메소드명을 동일하게 부여하여 메소드를 정의할 수 있도록 문법적으로 허용

5-3. Setter/Getter 메소드

  • 멤버 변수를 private 으로 선언한 후, 이 멤버 변수에 값을 할당할 때 사용하는 메소드를 Setter 메소드, 할당된 값을 리턴하는 메소드를 Getter 메소드라고 함

6. 정보은닉과 접근 제어 지시자

· 접근 제어 지시자의 범위 : public > protected > default > private

지시자 클래스 내부 동일 패키지 상속받은 클래스 이외의 영역
private O X X X
default O O X X
protected O O O X
public O O O O

'Java' 카테고리의 다른 글

[JAVA] Chapter 7. 추상클래스와 인터페이스  (0) 2023.11.07
[JAVA] Chapter 6. 상속  (0) 2023.11.07
[JAVA] Chapter 4. 배열  (0) 2023.11.07
[JAVA] Chapter 3-3. 이동 제어문  (0) 2023.11.07
[JAVA] Chapter 3-2. 제어문(반복문)  (0) 2023.11.07