[Java 기초] 클래스

Updated:

이번 포스트에서는 자바의 클래스에 대해서 알아보도록 하겠다. 👨‍🏫

📋 목차

  • 클래스 정의하는 방법
  • 객체 만드는 방법$($new 키워드 이해하기)
  • 메소드 기본형, 참조형 매개변수
  • 생성자 정의하는 방법
  • this 키워드 이해하기
  • 초기화 블럭을 통한 변수 초기화

클래스 정의하는 방법

객체란 실제로 존재하는 사물 또는 개념을 의미한다.

클래스란 객체를 생성하는데 사용되는 틀이다.

예를들어 빵을 틀에 찍어낸다고 생각해 본다면 빵틀은 빵을 만들어 내기 위해 사용되므로 클래스 이며 그 결과로 생성된 빵은 객체이다.

빵틀 = 클래스

빵 = 객체

객체는 멤버변수$($속성)와 메서드$($기능)으로 이루어져 있으며 클래스는 객체의 모든 멤버변수, 메서드가 정의되어 있다.

클래스로부터 객체를 생성하면 클래스에 정의된 멤버변수와 메서드를 가진 객체가 만들어진다.

TV 클래스를 정의한 예를 보겠다.

class Tv {
  
  // 멤버변수
  String color;
  boolean power;
  int channel;

  // 메서드
  void power() {
    power = !power
  }

  void channelUp() {
    channel++;
  }

  void channelDown() {
    channel--;
  }
}

객체 만드는 방법

// 클래스명 변수명; 
// 변수명 = new 클래스명();

Tv t; // Tv클래스 타입의 참조변수 t를 선언
t = new Tv(); // new연산자로 Tv 인스턴스를 생성하고,
// 대입 연산자로 Tv인스턴스의 주소를 참조변수 t에 저장

new 연산자

  • 인스턴스 $($객체)를 생성해주는 역할을 한다.
  • 힙 영역에 데이터를 저장할 메모리 공간을 할당받고 그 공간의 참조값을 객체에게 반환하고 생성자를 호출한다.

객체 배열 생성

Tv[] tvArr = new Tv[3]; // 참조변수 배열 생성

for(int i=0; i<tvArr.length; i++) {
  tvArr[i] = new Tv();
}

객체 배열은 참조변수들을 하나로 묶은 참조변수 배열이다.

즉, 객체 배열을 생성하면 배열안에는 객체가 아닌 객체의 주소가 저장된다.


메소드 기본형, 참조형 매개변수

기본형 매개변수 : 변수의 값을 읽기만 할 수 있다. $($read only)

참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다. $($read & write)

참조형 매개변수로 전달

메소드의 매개변수로 참조형변수를 전달한다.

참조형변수를 전달하여 값이 아닌 저장된 주소를 메소드에 넘겨줘야한다.

class Data { int x; }

class Example {
  public static void main(String args[]) {
    Data d = new Data();
    int[] arr = {10}; 
    d.x = 10;

    change(d.x);
    System.out.println("change(d.x)후 x = " + d.x); // x = 10

    change(d); // 참조형변수를 인자로 전달. 주소값을 전달
    System.out.println("change(d)후 x = " + d.x); // x = 1000

    change(arr);
    System.out.println("change(arr)후 arr = " + arr[0]); // arr = 1000


  }

  // 오버로딩
  static void change(int x) {
    x = 1000;
  }

  static void change(Data d) { // 참조형 매개변수
    d.x = 1000;
  }

  static void change(int[] arr) { // 참조형 매개변수
    arr[0] = 1000;
  }
}

반환타입이 참조형일 수도 있는데 이러한 경우에는 메서드가 객체의 주소를 반환하는것을 의미한다.


클래스 메서드와 인스턴스 메서드

클래스 메서드 $($static 메서드)

인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드를 클래스 메서드로 정의하고 메서드의 앞에 static을 붙인다. 주로 매개변수를 받아서 사용.

  • 클래스 메서드 내에서 인스턴스변수 사용불가.

  • 인스턴스 생성 없이도 호출가능

인스턴스 메서드

인스턴스 변수를 사용해서 메서드의 작업을 수행하는 메서드.

작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에는 static을 붙이는 것을 고려하는것이 좋다

인스턴스 메서드는 호출될 메서드를 찾는 과정 클래스 메서드 보다 추가로 더 필요하다.

클래스 메서드의 호출시간이 더 짧기 때문에 성능이 향상된다.

예제

class MyMath2 {
    long a, b;

    // 인스턴스 변수 a,b를 사용
    long add() { return a + b; }
    long subtract() { return a - b; }

    static long add(long a, long b) { return a + b; }
    static long subtract(long a, long b) { return a - b; }
}

class Example {
    public static void main(String[] args) {
        // 클래스메서드 호출. 인스턴스 생성없이 호출가능
        System.out.println(MyMath2.add(200, 100));
        System.out.println(MyMath2.subtract(200, 100));

        MyMath2 mm = new MyMath2(); // 객체 생성
        mm.a = 200;
        mm.b = 100;
        // 인스턴스메서드 호출
        System.out.println(mm.add());
        System.out.println(mm.subtract());
        }
}

생성자 정의하는 방법

생성자는 인스턴스가 생성되는 시기에 자동으로 호출되는 메서드이다.

인스턴스 생성 시에 실행되어야 할 작업을 위해서 사용되며 보통 변수 초기화에 사용된다.

생성자의 조건

  • 생성자의 이름은 클래스의 이름과 같다.
  • 생성자는 리턴 값이 없고 앞에 void 대신 아무것도 사용하지 않는다.
  • 모든 클래스에는 하나 이상의 생성자가 정의되어 있어야한다.

인스턴스 생성 과정

Animal dog = new Animal(); // Animal()이 바로 생성자!
  1. new 연산자에 의해 힙에 Animal 클래스의 인스턴스 생성.
  2. 생성자 Animal()이 호출되어 수행됨.
  3. new 연산자로 생성된 Animal 인스턴스의 주소가 반환되어 참조변수 dog에 저장됨.

기본 생성자 $($default constructor)

소스코드 $($.java)의 클래스에 생성자가 하나도 정의되어 있지 않은 경우 컴파일러는 자동으로 기본 생성자를 추가하여 컴파일한다.

// 클래스이름() { }
Animal() { }

매개변수가 있는 생성자

인스턴스 마다 각기 다른 고유의 값으로 초기화되야 하므로 매개변수가 있는 생성자를 통해 인스턴스 생성시에 인스턴스변수값을 초기화해 주는것으로 코드가 더 간결해진다.

class Card {
    static int width = 100;
    static int height = 200;

    String kind;
    int number;

    Card() {}

    Card(String k, int n) {
        kind = k;
        number = n;
    }
}

class Example {
    public static void main(String[] args) {
        Card c1 = new Card("Knight", 5);
        Card c2 = new Card("Queen", 7);
        System.out.println("c1 카드는 : " + c1.kind + ", " + c1.number);
        System.out.println("c2 카드는 : " + c2.kind + ", " + c2.number);
    }
}

this 키워드

this

인스턴스 자기 자신을 가리키는 참조변수.

멤버변수와 지역변수를 구분하는데 사용한다.

인스턴스의 주소가 저장되어있다.

모든 인스턴스 메서드에 지역변수로 숨어있다.

class Card {
  String kind;
  int number;

  Card(String kind, int number) {
    this.kind = kind; // kind = kind (X)
    this.number = number
  }

  /*
  다음과 같이 생성자 선언도 가능
  Card(String k, int n) {
    kind = k;
    number = n;
  }
  */
}

this(), this( 매개변수 )

  • 생성자 this().
  • 생성자의 이름으로 클래스이름 대신 this를 사용.
  • 생성자에서 같은 클래스의 다른 생성자를 호출할 때 사용.
  • 반드시 첫 줄에서만 호출 가능
class Card {
    String kind;
    int number;

    Card() {
        this("King", 1);
    }

    Card(String kind) {
        this(kind, 1);
    }

    Card(String kind, int number) {
        this.kind = kind;
        this.number = number;
    }
}

class Example {
    public static void main(String[] args) {
        Card c1 = new Card();
        Card c2 = new Card("Queen");

        System.out.println("c1 카드는 " + c1.kind + ", " + c1.number);
        System.out.println("c2 카드는 " + c2.kind + ", " + c2.number);
    }
}

출력

c1 카드는 King, 1
c2 카드는 Queen, 1

초기화 블럭을 통한 변수 초기화

초기화 블럭은 클래스변수와 인스턴스변수의 복잡한 초기화에 사용된다.

인스턴스 초기화 블럭에는 모든 생성자에서 공통으로 수행돼야 하는 코드를 넣는다.

덕분에 같은 코드를 생성자마다 써줄 필요가 없고 코드의 중복을 제거해준다.

초기화 블럭 실행시점

클래스 초기화 블럭 : 클래스가 처음 메모리에 로딩될 때

인스턴스 초기화 블럭 : 인스턴스가 생성될 때 마다.

예제

class Example {
    //명시적 초기화
    static int[] arr = new int[5];

    // 클래스 초기화 블럭
    static {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 10) + 1;
        }
    }

    // 인스턴스 초기화 블럭
    {
        System.out.println("인스턴스 초기화 블럭 실행.");
    }

    public void showText() {
        System.out.println("인스턴스가 생성되었습니다.");
    }

    public static void main(String[] args) {
        for(int i=0; i<arr.length; i++) {
            System.out.println("arr[" + i + "] : " + arr[i]);
        }
        System.out.println();

        Example ex = new Example();
        ex.showText();
    }
}

출력

arr[0] : 6
arr[1] : 3
arr[2] : 5
arr[3] : 8
arr[4] : 2

인스턴스 초기화 블럭 실행.
인스턴스가 생성되었습니다.

이처럼 배열이나 예외처리가 필요한 초기화에서 초기화 블럭을 통해 쉽게 값을 초기화 할 수 있다.


참조
Java의 정석 $($남궁 성)
whiteship 자바 라이브 스터디

Categories:

Updated:

Leave a comment