인프런/김영한 자바

[김영한의 실전 자바 기본편] - 1. 클래스와 데이터

sson-coding 2025. 9. 2. 21:44

자바 세상은 클래스와 객체로 이루어져 있는만큼 클래스와 객체라는 개념은 중요하다.
클래스와 객체에 대해서 알아보자.

클래스

클래스와 사용자 정의 타입

타입은 데이터의 종류나 형태를 뜻한다. 앞서 배웠듯이 int 는 정수 타입, String 은 문자 타입이다.
그렇다면 위에서 작성한 것 처럼 학생(Student) 이라는 타입을 만들면 되지 않을까?
클래스를 사용하면 int, String 과 같은 타입을 직접 만들 수 있다.

사용자가 직접 정의하는 사용자 정의 타입을 만들려면 설계도가 필요하다.
우리는 이 설계도를 클래스 라고 부른다.

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

클래스 vs 객체 vs 인스턴스

클래스(Class)

클래스는 객체를 생성하기 위한 틀,설계도 이다.
객체가 가져야 할 속성(변수)과 기능(메서드)를 정의한다.

붕어빵 틀을 생각해보자. 붕어빵 틀은 붕어빵이 아니고, 이렇게 생긴 붕어빵이 나왔으면 좋겠다고 만드는 틀일 뿐이다. 실제 먹을 수 있는 팥 붕어빵을 객체 또는 인스턴스라 한다.

객체(Object)

객체는 클래스에서 정의한 속성과 기능을 가진 실체이고, 서로 독립적인 상태를 가진다.
예를 들어 위 코드에서 student1 은 학생1 의 속성을 가지는 객체이고, student2 는 학생2의 속성을 가지는 객체이다.
student1 과 student2 는 같은 클래스에서 만들어졌지만, 서로 다른 객체인 것이다.

인스턴스(Instance)

인스턴스는 특정 클래스로부터 생성된 객체를 의미한다.
그래서 객체와 인스턴스는 용어가 자주 혼용된다.
인스턴스는 주로 객체가 어떤 클래스에 속해 있는지 강조할 때 사용한다.
예를 들어, student1 객체는 Student 클래스의 인스턴스다 라고 표현한다.

객체 vs 인스턴스

즉, 둘 다 클래스에서 나온 실체라는 의미에서 비슷하게 사용되지만, 인스턴스는 객체보다 좀 더 관계에 초점을 맞춘 단어이다.
보통 student1 은 Student 의 인스턴스이다. 라고 특정 클래스와의 관계를 명확히 할 때 인스턴스라는 용어를 주로 사용한다.

좀 더 쉽게 풀어보자면, 모든 인스턴스는 객체이지만, 우리가 인스턴스라고 부르는 순간은 특정 클래스로부터 그 객체가 생성되었음을 강조하고 싶을 때이다.


클래스 도입

클래스를 사용해서 학생이라는 개념을 만들고, 각각의 학생 별로 본인의 이름, 나이, 성적을 관리할 수 있도록 코드를 작성해보자.

class 키워드를 사용해서 학생 클래스(Student) 를 정의한다.
학생 클래스 내부에는 이름(name), 나이(age), 성적(grade) 변수를 가지게 된다.

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

이렇게 클래스에 정의한 변수들을 멤버 변수, 필드 라고 한다.

  • 멤버 변수 : 특정 클래스에 소속된 멤버
  • 필드 : 데이터 항목을 가리키는 전통적인 용어

자바에서는 멤버 변수, 필드는 같은 뜻으로, 클래스에 소속된 변수를 뜻한다.

이제 학생 클래스를 사용하는 코드를 작성해보자.

public class ClassStart {
 public static void main(String[] args) {
     Student student1;
     student1 = new Student();
     student1.name = "학생1";
     student1.age = 15;
     student1.grade = 90;

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

     System.out.println("이름:" + student1.name + " 나이:" + student1.age + " 
    성적:" + student1.grade); System.out.println("이름:" + student2.name + " 나이:" + student2.age + " 
    성적:" + student2.grade);
 }
}

---실행 결과---
이름:학생1 나이:15 성적:90
이름:학생2 나이:16 성적:80

이제 위 코드를 하나씩 분석해보자.

변수 선언

Student student1

  • Student 타입을 받을 수 있는 변수를 선언한다.

객체 생성

student1 = new Student()

  • 객체를 사용하려면 먼저 설계도인 클래스를 기반으로 객체를 생성해야 한다.
  • new 는 새로 생성한다는 뜻으로, Student 클래스 정보를 기반으로 새로운 객체를 생성하라는 뜻이다. 이렇게 하면 메모리에 실제 Student 객체를 생성한다.
  • Student 클래스는 name,age,grade 멤버 변수를 가지고 있다. 이 변수를 사용하는데 필요한 메모리 공간도 함께 확보한다.

참조값 보관

student1 = x001

  • 객체를 생성하면 자바는 메모리 어딘가에 있는 이 객체에 접근할 수 있는 참조값(주소)을 반환한다.
    • 여기서 x001 이라고 표현한 것이 참조값이다.
  • new 키워드를 통해 객체가 생성되고 나면 참조값을 반환한다.
  • Student student1 변수는 이제 메모리에 존재하는 실제 Student 객체의 참조값을 가지고 있다.
  • student1 변수를 통해 메모리에 있는 실제 객체를 접근하고 사용할 수 있다.

참조값을 변수에 보관해야 하는 이유

객체를 생성하는 new Student() 코드 자체에는 아무런 이름이 없다. 이 코드는 단순히 클래스를 기반으로 메모리에 객체를 만드는 것이라 생성한 객체에 접근할 수 있는 방법이 필요하다.
이런 이유로 객체를 생성할 때 반환되는 참조값을 어딘가에 보관해두어야 한다.

객체 사용 및 값 대입

클래스를 통해 생성한 객체를 사용하려면 먼저 메모리에 존재하는 객체에 접근해야 한다.

객체에 접근 하려면 . 을 사용하면 된다.

//객체 값 대입
student1.name = "학생1";
student1.age = 15;
student1.grade = 90;
//객체 값 사용
System.out.println("이름:" + student1.name + " 나이:" + student1.age + " 성적:" +
student1.grade);

객체에 값을 대입하는 순서를 풀어보면 다음과 같다.

student1.name="학생1" //1. student1 객체의 name 멤버 변수에 값 대입
x001.name="학생1" //2.변수에 있는 참조값을 통해 실제 객체에 접근, 해당 객체의 name 멤버 변수에
값 대입
  1. student1. 이라고 하면 student1 변수가 가지고 있는 참조값을 통해 실제 객체에 접근한다.
  2. student1 은 참조값을 가지고 있으므로 , 참조값 위치에 있는 객체에 접근한다.
  3. 객체가 있는 곳의 멤버 변수에 데이터를 저장한다.

배열 사용

배열을 사용하면 특정 타입을 연속한 데이터 구조로 묶어서 편리하게 관리할 수 있다.

배열에 참조값 대입

Student 를 담을 수 있는 배열을 생성하고, 해당 배열에 student1,2 인스턴스를 보관하자.

Student[] students = new Student[2]

배열에는 아직 참조값을 대입하지 않았기 때문에 null 로 초기화가 된다.

이제 배열에 객체를 보관하자.

students[0] = student1;
students[1] = student2;
//자바에서 대입은 항상 변수에 들어 있는 값을 복사한다.
students[0] = x001;
students[1] = x002;

student1,student2 에는 참조값이 보관되어 있다. 따라서 이 참조값이 배열에 저장된다.

이제 배열은 참조값을 가지고 있기 때문에 Student 인스턴스에 모두 접근할 수 있게 된다.

배열에 들어있는 객체 사용

배열에 들어있는 객체를 사용하려면 먼저 배열에 접근하고, 객체에 접근하면 된다.

System.out.println(students[0].name); //배열 접근 시작
System.out.println(x005[0].name); //[0]를 사용해서 x005 배열의 0번 요소에 접근
System.out.println(x001.name); //.(dot)을 사용해서 참조값으로 객체에 접근
System.out.println("학생1");