기본 콘텐츠로 건너뛰기

방송대 Java프로그래밍 3강: 배열 처리와 클래스 생성·접근 규칙

Java프로그래밍 3강 - Java 기본 문법(2)과 클래스와 상속(1)

방송대 Java프로그래밍 3강: 배열 처리와 클래스 생성·접근 규칙

학생별 점수를 모으려면 배열이 필요하고, 키보드 값을 읽으려면 Scanner가 필요하며, 반지름과 넓이 계산을 한 단위로 묶으려면 클래스가 필요하다. 문제는 문법 이름을 아는 데서 끝나지 않는다. 선언과 생성 중 무엇을 해야 하는지, 어떤 입력 메서드를 짝지을지, 필드를 어디까지 공개할지, 기본 생성자가 언제 사라지는지를 조건에 따라 판단해야 한다.

값 하나가 아니라 같은 자료형의 여러 값을 다루면 배열을 선택한다

배열은 같은 자료형의 원소를 정해진 개수만큼 보관하는 객체다. 각 원소에는 0부터 시작하는 숫자 인덱스로 접근한다. 예를 들어 원소가 5개라면 사용할 수 있는 인덱스는 0부터 4까지다.

배열을 사용할 때는 참조 변수 선언, 배열 객체 생성, 원소 초기화를 구분해야 한다. 선언만 한 int[] scores;에는 아직 원소 공간이 없다. new int[5]를 실행해야 길이가 5인 배열 객체가 생기고 그 참조값이 변수에 대입된다.

int[] scores;          // 배열 참조 변수만 선언
scores = new int[5];  // 길이 5인 배열 객체 생성
scores[0] = 87;       // 첫 번째 원소 사용

int[] primes = {2, 3, 5, 7, 11}; // 선언과 동시에 초기화

new int[5]로 만든 배열의 int 원소는 0으로 자동 초기화된다. 참조형 원소를 가진 배열이라면 각 원소는 null로 초기화된다. 배열의 크기는 초기화하거나 생성할 때 정해지며, 선언부의 대괄호 안에 크기를 쓰는 int values[5];는 Java 문법이 아니다.

판정 규칙: 대괄호가 자료형·변수 이름과 붙어 있으면 “배열 참조 변수의 선언”, new 자료형[크기]가 있으면 “원소 공간의 생성”, 중괄호에 값이 있으면 “초기값 지정”으로 구분한다.

2차원 배열은 행마다 길이가 같다고 가정하면 안 된다

Java의 2차원 배열은 배열을 원소로 갖는 배열로 이해하면 쉽다. 각 행이 별도의 배열이므로 행마다 길이가 달라도 된다. 다음 배열의 바깥 길이는 2지만, 0번 행의 길이는 2이고 1번 행의 길이는 3이다.

int[][] grid = {
    {0, 1},
    {10, 11, 12}
};

for (int i = 0; i < grid.length; i++) {
    for (int j = 0; j < grid[i].length; j++) {
        System.out.println(grid[i][j]);
    }
}
표현판단 근거
grid.length2행 배열이 2개
grid[0].length20번 행 원소는 0, 1
grid[1].length31번 행 원소는 10, 11, 12
출력 순서0, 1, 10, 11, 12각 행의 실제 길이까지 순회

안쪽 반복문의 조건을 j < grid[0].length로 고정하면 더 긴 행의 마지막 원소를 빠뜨리거나 더 짧은 행에서 범위를 벗어날 수 있다. 현재 처리 중인 행의 길이인 grid[i].length를 사용해야 한다.

+의 결과는 왼쪽 값이 문자형인지 문자열인지 먼저 본다

String 클래스는 문자열을 표현하고 처리하는 참조형이다. 문자열 리터럴은 이중 따옴표를 사용하며, String word = "Java";처럼 기본형 변수와 비슷한 모양으로 초기화할 수 있다. 참조형 변수이므로 아직 객체를 가리키지 않는 특별한 값 null도 가질 수 있다.

+는 문자열이 결합에 참여하면 다른 값을 문자열로 바꾸어 연결한다. 그러나 작은따옴표의 'A'는 문자열이 아니라 char 값이므로 숫자와 더할 때 수치 연산이 일어난다.

System.out.println('A' + 0);   // 65
System.out.println("A" + 0);  // A0

int count = 6;
System.out.println("count=" + count); // count=6
표현처리결과
'A' + 0char가 수치 연산에 참여65
"A" + 0문자열 결합A0
"count=" + 6정수 6을 문자열로 변환해 연결count=6

print()println()은 전달받은 값을 문자열 형태로 화면에 출력한다. System.out은 화면 출력에 사용하는 객체이며, println()은 출력 뒤 줄을 바꾼다는 점에서 print()와 다르다.

Scanner는 “다음 값을 검사하는 메서드”와 “읽는 메서드”를 짝지어 쓴다

Scanner는 키보드나 파일에서 문자열·기본형 값을 입력받을 때 사용하는 클래스다. 키보드 입력에는 System.in을 전달해 Scanner 객체를 만들며, 사용 전에 java.util.Scanner를 가져온다.

입력 단위존재·형식 검사실제 읽기
다음 단어hasNext()next()
다음 정수hasNextInt()nextInt()
다음 실수hasNextDouble()nextDouble()
다음 한 줄hasNextLine()nextLine()

다음 예제는 입력의 다음 토큰이 정수인 동안만 값을 읽어 합계를 구한다. 학습을 위해 입력을 8 13 5 end라고 가정하면 8, 13, 5를 더한 26을 출력하고 end 앞에서 반복을 끝낸다.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int total = 0;

        while (sc.hasNextInt()) {
            total += sc.nextInt();
        }

        System.out.println(total);
    }
}

hasNextInt()는 다음 토큰을 소비하지 않고 정수인지 검사하고, nextInt()가 실제로 읽는다. 검사만 반복하면 입력 위치가 이동하지 않고, 검사 없이 형식이 다른 토큰을 nextInt()로 읽으면 실패할 수 있다. 따라서 검사와 읽기를 한 쌍으로 설계한다.

클래스 정의에서는 상태·초기화·행위를 서로 다른 자리에 둔다

클래스는 동종 객체를 표현할 데이터 필드와 메서드를 정의한다. 클래스 머리에는 접근 제어자와 클래스 이름을 쓰며, 필요할 때 부모 클래스는 extends, 구현할 인터페이스는 implements로 표시한다. 클래스 몸체에는 데이터 필드, 생성자와 메서드가 놓인다.

class Circle {
    private double radius;          // 상태

    public Circle(double radius) {  // 초기화
        this.radius = radius;
    }

    public double getArea() {       // 행위
        return radius * radius * 3.14;
    }

    public double getRadius() {
        return radius;
    }
}

메서드는 헤더와 몸체로 구성된다. 헤더에는 접근 제어자, 반환형, 메서드 이름, 매개변수 목록이 들어가며 필요하면 예외 선언이 뒤따른다. getArea()의 반환형은 double이고 매개변수는 없으며, 몸체의 return이 계산 결과를 호출한 곳으로 돌려준다.

this.radiusthis는 현재 객체를 가리킨다. 생성자의 매개변수와 필드 이름이 모두 radius일 때 this.radius = radius;는 “현재 객체의 필드에 매개변수 값을 저장한다”는 뜻이다.

인스턴스 멤버와 클래스 멤버는 소유 주체로 구분한다

각 객체가 따로 소유하는 데이터 필드와 메서드를 인스턴스 변수·인스턴스 메서드라고 한다. 반면 클래스에 속한 객체들이 공유하도록 정의한 멤버는 클래스 변수·클래스 메서드다. 객체의 상태는 주로 데이터 필드로, 그 상태를 이용한 행위는 메서드로 구현한다.

판단 질문인스턴스 멤버클래스 멤버
누가 소유하는가?개별 객체클래스 자체
값이 객체마다 달라지는가?가능객체들이 공유
대표 접근 기준객체 참조와 점 연산자클래스 이름을 기준으로 이해

원의 반지름은 원 객체마다 달라질 수 있으므로 radius는 인스턴스 필드가 자연스럽다. 반대로 모든 원 객체가 공유해야 하는 하나의 정보라면 클래스 멤버가 적합한지 검토한다. 이름을 외우기보다 “객체마다 독립적인가, 클래스 전체가 공유하는가”를 먼저 묻는다.

접근 제어자는 사용자를 네 범위로 나누어 판정한다

접근 제어자는 클래스나 멤버를 사용할 수 있는 범위를 제한한다. 멤버 기준으로는 현재 클래스, 같은 패키지의 다른 클래스, 다른 패키지의 자식 클래스, 그 밖의 외부 클래스라는 네 위치를 구분하면 된다.

멤버 접근 수준현재 클래스같은 패키지다른 패키지의 자식 클래스그 밖의 외부
private가능불가불가불가
생략가능가능불가불가
protected가능가능가능불가
public가능가능가능가능

최상위 클래스의 선언에서는 접근 제어자를 생략해 패키지 범위로 두거나 public으로 공개할 수 있다. privateprotected를 클래스 선언에 쓰는 경우는 내부 클래스에서 다룬다. 또한 abstractfinal은 사용 범위를 정하는 접근 제어자가 아니라 클래스의 성격을 지정하는 제어자다.

선택 순서: 정보 은닉이 필요한가 → 같은 패키지와 공유해야 하는가 → 다른 패키지의 자식 클래스까지 열어야 하는가 → 모든 곳에 공개해야 하는가를 차례로 묻는다.

private 필드는 직접 노출하지 않고 공개 메서드로 경계를 만든다

앞의 Circle에서 radiusprivate이므로 다른 클래스가 circle.radius로 직접 읽거나 바꿀 수 없다. 대신 공개된 getRadius()getArea()를 통해 필요한 정보와 기능을 제공한다.

public class Main {
    public static void main(String[] args) {
        Circle circle = new Circle(5.0);

        // System.out.println(circle.radius); // private이라 컴파일 오류
        System.out.println(circle.getRadius());
        System.out.println(circle.getArea());
    }
}

출력은 반지름 5.0과 넓이 78.5다. 넓이는 5.0 × 5.0 × 3.14 = 78.5로 계산된다. 필드를 감춘다는 것은 데이터를 전혀 쓰지 못하게 한다는 뜻이 아니라, 클래스가 허용한 메서드를 통해 사용 규칙을 통제한다는 뜻이다.

변수 선언·객체 생성·멤버 사용은 세 문장으로 분해한다

Circle circle;은 Circle 객체를 가리킬 수 있는 참조 변수를 선언한 것이며 객체는 아직 없다. new Circle(5.0)은 메모리를 할당하고 생성자를 호출해 객체를 만든다. 대입 연산자는 생성된 객체의 참조값을 circle에 저장한다.

Circle circle;               // 참조 변수 선언
circle = new Circle(5.0);   // 객체 생성 후 참조값 대입
double area = circle.getArea(); // 점 연산자로 메서드 호출
  1. 선언: 어떤 클래스의 객체를 가리킬 변수인지 정한다.
  2. 생성: new가 메모리 공간을 확보하고 생성자를 호출한다.
  3. 사용: 객체 변수와 점 연산자로 접근 가능한 필드나 메서드를 선택한다.

객체 변수는 메서드 인자로 전달하거나 부모 유형 변수에 대입하는 데도 사용할 수 있다. 상속 관계의 자세한 규칙은 다음 차시의 범위이며, 현재는 클래스가 객체의 자료형으로도 사용된다는 점을 잡아 두면 된다.

기본 생성자는 “생성자를 하나도 쓰지 않았을 때만” 자동 제공된다

생성자는 객체가 만들어질 때 자동으로 호출되어 필드 초기화와 같은 작업을 하는 특별한 메서드다. 이름은 클래스 이름과 같고 반환형을 쓰지 않는다. 한 클래스에서 매개변수의 개수나 자료형이 다른 여러 생성자를 정의하는 생성자 오버로딩도 가능하다.

클래스에 작성한 생성자컴파일러의 기본 생성자 제공가능한 호출 예
하나도 없음인자 없는 생성자를 자동 제공new Circle()
Circle(double r)만 있음자동 제공하지 않음new Circle(5.0)
인자 없는 생성자와 매개변수 생성자를 모두 정의작성한 두 생성자를 사용두 호출 모두 가능

“인자가 없는 생성자는 언제나 있다”는 생각은 틀리다. 생성자를 하나라도 직접 정의하면 컴파일러는 기본 생성자를 자동으로 만들지 않는다. Circle(double radius)만 정의한 클래스에서 new Circle()을 사용하려면 인자 없는 생성자를 직접 추가해야 한다.

생성자 몸체 첫 줄에 부모 생성자의 명시적 호출이 없으면 super(); 호출이 자동으로 들어간다. 따라서 부모 클래스에 접근 가능한 인자 없는 생성자가 있는지도 확인해야 한다. 이 규칙은 다음 차시에서 상속과 생성자의 연결을 배울 때 중요해진다.

문법 문제는 대상·시점·범위 세 질문으로 해결한다

  • 대상: 같은 자료형의 여러 값이면 배열, 텍스트면 String, 외부 입력이면 Scanner, 상태와 행위의 묶음이면 클래스를 검토한다.
  • 시점: 배열 참조 선언과 원소 공간 생성, 객체 변수 선언과 new 객체 생성을 분리한다.
  • 범위: 배열은 현재 행의 length, Scanner는 다음 입력 형식, 클래스 멤버는 접근 제어 범위를 확인한다.
  • 초기화: 배열 원소의 기본값과 생성자가 정하는 객체 필드값을 구분한다.
  • 호출: 메서드는 반환형·매개변수와 맞춰 호출하고, 생성자는 클래스 이름 및 인자 목록과 맞춘다.

코드를 읽을 때 먼저 “지금 다루는 대상이 배열·문자열·입력 객체·일반 객체 중 무엇인가”를 정하고, 다음으로 “선언·생성·사용 중 어느 시점인가”를 찾은 뒤, 마지막으로 “인덱스·입력 형식·접근 제어·생성자 인자라는 범위 조건을 지켰는가”를 확인하자. 이 순서면 서로 다른 문법 오류를 하나의 점검 체계로 진단할 수 있다.

예상문제 10선

1. Java 배열 선언으로 컴파일 오류가 발생하는 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 대괄호를 자료형 뒤에 둔 올바른 1차원 배열 참조 선언이다.
  • ② 오답: 대괄호를 변수 이름 뒤에 두는 형태도 Java에서 허용된다.
  • ③ 오답: 2차원 배열을 가리킬 참조 변수를 올바르게 선언했다.
  • ④ 정답: Java에서는 선언 대괄호에 크기를 쓰지 않고 생성이나 초기화 시 크기를 정한다.

2. int[][] a = {{2, 4, 6}, {9}};일 때 a.length + a[1].length의 값은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 바깥 배열의 행 개수만 계산하고 1번 행의 길이를 더하지 않았다.
  • ② 정답: 행은 2개이고 1번 행의 원소는 1개이므로 2 + 1 = 3이다.
  • ③ 오답: 전체 원소 수 4를 구한 값이며 문제의 두 length 합과 다르다.
  • ④ 오답: 전체 원소 수와 행 수를 다시 더한 값으로 식을 잘못 해석했다.

3. 다음 출력 결과의 연결로 옳은 것은? 'A' + 0"A" + 0을 차례로 출력한다.

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 작은따옴표의 문자는 수치 연산으로 65가 되고, 문자열은 0을 이어 붙여 A0가 된다.
  • ② 오답: char 연산과 문자열 결합의 결과를 서로 뒤바꿨다.
  • ③ 오답: 두 식 모두 + 0 연산이 있으므로 피연산자를 무시할 수 없다.
  • ④ 오답: 문자·문자열 피연산자를 모두 버린 결과로 Java의 + 처리와 맞지 않는다.

4. 입력의 다음 토큰이 정수인지 확인한 뒤 실제 정수로 읽는 올바른 메서드 순서는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 단어 존재 검사와 한 줄 읽기를 섞어 정수 형식 판정이 없다.
  • ② 오답: 읽기를 먼저 하면 형식이 맞지 않을 때 사전 검사의 보호를 받지 못한다.
  • ③ 정답: 정수 여부를 소비 없이 검사한 뒤 같은 형식의 읽기 메서드로 값을 가져온다.
  • ④ 오답: 실수 검사와 문자열 읽기를 조합해 요구한 정수 입력과 맞지 않는다.

5. 클래스의 메서드 헤더에 포함되는 요소로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 원소값과 실행 결과는 메서드 헤더를 정의하는 문법 요소가 아니다.
  • ② 오답: 메모리 주소는 개발자가 헤더에 직접 기록하지 않는다.
  • ③ 오답: 바이트코드와 입력 스트림은 메서드 선언부의 구성 요소가 아니다.
  • ④ 정답: 호출 가능 범위, 결과 자료형, 이름과 입력 조건을 헤더가 나타낸다.

6. 같은 클래스 안에서만 직접 사용할 수 있게 반지름 필드를 숨기려 한다. 가장 적합한 선언은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: private은 선언한 클래스 내부로 직접 접근 범위를 제한한다.
  • ② 오답: protected는 같은 패키지와 자식 클래스에도 범위를 연다.
  • ③ 오답: public은 외부 모든 클래스에서 접근할 수 있어 은닉 목표와 반대다.
  • ④ 오답: 접근 제어자 생략은 같은 패키지의 다른 클래스까지 허용한다.

7. 접근 제어자에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 접근 제어자를 생략한 멤버는 같은 패키지의 다른 클래스에서도 사용할 수 있다.
  • ② 정답: 강의의 범위표에서 protected는 패키지 관계와 상속 관계를 모두 고려한다.
  • ③ 오답: public은 패키지 밖을 포함해 가장 넓은 접근을 허용한다.
  • ④ 오답: 두 키워드는 클래스 성격을 제어하지만 접근 범위를 정하는 접근 제어자가 아니다.

8. Circle c = new Circle(5.0);에서 일어나는 일을 가장 알맞게 설명한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 객체 생성 문장에는 문자열 변환이나 배열 저장 과정이 없다.
  • ② 오답: 참조 변수에는 객체 자체가 아니라 객체를 가리키는 참조값이 대입된다.
  • ③ 오답: 생성자는 객체 생성 시 호출되며 클래스를 새로 정의하는 절차가 아니다.
  • ④ 정답: 선언, new에 의한 생성, 생성자 호출, 참조값 대입을 순서대로 설명했다.

9. 강의의 원 넓이식 radius * radius * 3.14를 사용할 때 반지름이 4.0이면 결과는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 반지름을 제곱하지 않고 4 × 3.14만 계산했다.
  • ② 오답: 지름 8에 3.14를 곱해 원주 계산과 넓이 계산을 혼동했다.
  • ③ 정답: 4.0 × 4.0 × 3.14 = 16 × 3.14 = 50.24다.
  • ④ 오답: 본문의 반지름 5.0인 원 넓이를 현재 조건에 그대로 적용했다.

10. Circle(double radius) 생성자만 정의된 클래스에서 new Circle()이 컴파일되지 않는다. 가장 적절한 해결은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 생성자를 하나 정의하면 기본 생성자는 자동 제공되지 않으므로 호출과 정의의 인자 목록을 맞춰야 한다.
  • ② 오답: 필드 접근 범위와 컴파일러의 기본 생성자 제공 조건은 서로 다른 규칙이다.
  • ③ 오답: 일반 메서드의 반환형 변경은 생성자 오버로딩이나 호출 인자와 관계없다.
  • ④ 오답: 배열 크기는 클래스의 생성자 선언 여부에 영향을 주지 않는다.

참고 자료와 작성 기준

이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. 배열 추적, 문자열 연산 비교, Scanner 입력 판단, 접근 범위표와 생성자 오류 진단은 학습자의 이해를 돕도록 구성하고 검토했습니다.

  • 작성·편집: 올에이클래스 학습연구팀
  • 주요 근거: 한국방송통신대학교 Java프로그래밍 3강 「Java 기본 문법(2), 클래스와 상속(1)」 강의자료(교재 2장-2, 3장-1)
  • 보충 자료: 별도의 외부 자료를 본문 근거로 사용하지 않음
  • 편집 원칙: 올에이클래스 편집 정책
  • 최종 내용 검토: 2026-09-01

댓글