Java 클래스 설계: 메서드 시그니처, 생성자 및 배열 활용

메서드 정의와 시그니처의 이해

자바에서 메서드의 고유성을 결정하는 요소는 메서드 이름과 매개변수 리스트를 합친 '시그니처(Signature)'입니다. 반환값은 시그니처에 포함되지 않으므로, 메서드를 구분할 때 반환 타입만으로는 부족합니다.

  • 오버로딩 (Overloading): 하나의 클래스 내에서 동일한 이름을 가지되, 매개변수의 개수나 타입이 서로 다른 메서드를 선언할 수 있습니다. 컴파일러는 호출 시점에 전달된 인자에 가장 적합한 메서드를 자동으로 선택하여 바인딩합니다.

객체 초기화와 생성자(Constructor)

생성자는 인스턴스 메모리를 할당받고 멤버 변수에 초기 값을 설정하는 특수한 메서드입니다.

  1. 클래스 이름과 완전히 동일해야 합니다.
  2. 반환 타입을 명시하지 않습니다(void 포함 금지).
  3. 객체를 생성(new)하는 순간 자동 실행됩니다.
  4. 사용자가 작성하지 않으면 컴파일러가 기본 무반환 생성자를 제공하지만, 명시적 생성자가 있으면 이 기본 생성자는 사라집니다.
  5. 매개변수 조합에 따라 여러 개의 생성자를 정의하여 오버로딩이 가능합니다.

this 키워드는 현재 실행 중인 객체 자신을 가리킵니다. 주로 필드와 지역 변수의 충돌을 해결하거나, 같은 클래스 내의 다른 생성자를 호출할 때 (this()) 사용됩니다.

참조 형식 배열과 다차원 구조

배열의 요소 타입에 따라 초기화 상태가 달라집니다. 기본数据类型(primitive type) 배열은 모든 요소가 디폴트 값 (예: 정수는 0) 으로 채워지지만, 참조 형식 (class, interface 등) 배열의 경우 모든 요소가 null로 초기화됩니다.

다차원 배열 역시 각 행 (행 배열) 을 개별적으로 새로운 배열 객체로 생성해야 사용 가능한 '불규칙 배열(Jagged Array)' 형태로 구성할 수 있습니다.

코드 실습: 오버로딩과 참조 배열

package com.oop.core;
/* 메서드 오버로딩 테스트 */
public class OperationTester {
    public static void main(String[] args) {
        DataHandler handler = new DataHandler();
        
        // 다양한 서명이 있는 메서드 호출
        handler.process(); 
        handler.execute("User_01");
        handler.register("Admin", 1);
        handler.setPriority(10, "High");
    }
}

class DataHandler {
    void process() {
        System.out.println("기본 작업 수행");
    }
    
    void execute(String userId) {
        System.out.println("사용자 ID 로 작업 시작: " + userId);
    }
    
    void register(String name, int grade) {
        System.out.println(name + " 등급: " + grade);
    }
    
    // 인수 순서가 다르면 오버로딩으로 인정됨
    void setPriority(int val, String label) {
        System.out.println("우선순위: " + val + " - " + label);
    }
}

실전 적용: 좌표 시스템 및 블록 배치

위치 정보를 관리하기 위한 클래스와 이를 그룹화하는 블록 형태의 패턴을 구현해 봅니다.

package com.oop.core;

// 좌표를 나타내는 클래스
public class GridPoint {
    int x; 
    int y;

    public GridPoint() {
        this(0, 0);
    }

    public GridPoint(int side) {
        this(side, side);
    }

    public GridPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // 위치 변경
    public void shift(int dx, int dy) {
        this.x += dx;
        this.y += dy;
    }

    @Override
    public String toString() {
        return "[" + x + "," + y + "]";
    }
}
```
package com.oop.core;

// 네 개의 점으로 구성된 특정 모양 (T 자형 대안)
public class ShapeBlockT {
    private GridPoint[] vertices;

    public ShapeBlockT(int startX, int startY) {
        // 4 개의 포인트를 가진 배열 생성
        vertices = new GridPoint[4];
        
        vertices[0] = new GridPoint(startX, startY);
        vertices[1] = new GridPoint(startX + 1, startY);
        vertices[2] = new GridPoint(startX + 2, startY);
        vertices[3] = new GridPoint(startX + 1, startY + 1);
    }

    public void moveDown() {
        for(GridPoint pt : vertices) {
            pt.shift(0, 1); // y 축 증가
        }
    }

    public void printInfo() {
        for(int i = 0; i < vertices.length; i++) {
            System.out.println("Vertex " + i + ": " + vertices[i].toString());
        }
    }
}

public class MainApp {
    public static void main(String[] args) {
        // 1 차원 참조 배열 활용
        GridPoint[] coords = new GridPoint[2];
        coords[0] = new GridPoint(10, 20);
        coords[1] = new GridPoint(30, 40);
        
        System.out.println("Coords: " + coords[1]);
        
        // 불규칙 2 차원 배열
        int[][] jagged = new int[3][];
        jagged[0] = new int[]{1, 2};
        jagged[1] = new int[]{3, 4, 5};
        jagged[2] = new int[]{6};
        
        // ShapeBlock 테스트
        ShapeBlockT myT = new ShapeBlockT(5, 5);
        System.out.println("--- Initial ---");
        myT.printInfo();
        
        myT.moveDown();
        System.out.println("--- After Move ---");
        myT.printInfo();
    }
}

학습 점검

문제 1: 오버로딩 식별

다음 코드가 실행될 때 출력되는 값은 무엇이며 그 이유는 무엇인가요?

class Test {
    int calculate(int a, int b) { return a * b; }
    String calculate(String s1, String s2) { return s1 + s2; }
}
// 호출: Test t = new Test();
// System.out.println(t.calculate("3", "4"));

정답: 문자열 연결 결과인 "34" 가 출력됩니다.
컴파일러는 인자의 타입이 문자열 (String) 임을 인지하므로, int 가 아닌 String 매개변수를 가진 오버로드된 메서드를 선점합니다.

문제 2: 생성자 규칙 확인

아래 설명 중 옳지 않은 것은 무엇입니까?

  • A. 생성자는 반드시 클래스 이름과 같아야 한다.
  • B. 생성자에 void 를 명시하면 일반 메서드로 인식된다.
  • C. 사용자가 생성자를 하나라도 만들면 기본 무인자 생성자는 자동 생성되지 않는다.
  • D. 생성자는 오버로딩이 불가능하다.

정답: D 입니다. 생성자는 매개변수의 조합을 달리하여 여러 개 정의할 수 있으며, 이를 생성자의 오버로딩이라고 부릅니다.

태그: java OOP method-overloading constructors array-types

8월 1일 09:59에 게시됨