본문 바로가기
Course/Java

[java-basic] 1. 클래스와 데이터

by Lpromotion 2024. 12. 6.
김영한의 실전 자바 - 기본편

 

목차
 

1. 클래스

클래스를 사용해서 학생이라는 개념을 만들고, 각각의 학생 별로 본인의 이름, 나이, 성적을 관리한다.

 

Student 클래스

package class1;

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

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

 

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

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

 

클래스는 관례상 대문자로 시작하고 낙타 표기법을 사용한다.

 

학생 클래스를 사용하는 코드

ClassStart3

package class1;

public class ClassStart3 {

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

        Student student2 = new Student(); //x002
        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);
    }
}

 

클래스와 사용자 정의 타입

  • 타입은 데이터의 종류나 형태를 나타냄
  • 사용자가 직접 정의하는 사용자 정의 타입을 만들려면 설계도가 필요하고, 이 설계도가 클래스이다.
  • 설계도인 클래스를 사용해서 실제 메모리에 만들어진 실체를 객체 또는 인스턴스라 한다.
  • ex) 붕어빵 틀 -> 설계도, 붕어빵 -> 객체(인스턴스)

학생(`Student`) 클래스를 기반으로 학생1(`student1`), 학생2(`student2`) 객체 또는 인스턴스를 만들었다.

 

1. 변수 선언

Student student1; // Student 변수 선언

`Student`는 `Student` 타입의 객체(인스턴스)를 받을 수 있다.

 

2. 객체 생성

student1 = new Student(); // Student 인스턴스 생성
  • 객체를 사용하려면 먼저 설계도인 클래스를 기반으로 객체(인스턴스)를 생성해야 한다.
  • `new` 는 새로 생성한다는 뜻이다. `new Student()`는 Student 클래스 정보를 기반으로 새로운 객체를 생성하라는 뜻이다. 이렇게 하면 메모리에 실제 Student 객체(인스턴스)를 생성한다.
  • 객체를 생성할 때는 `new 클래스명()` 을 사용하면 된다. 마지막에 () 도 추가해야 한다.
  • `Student` 클래스는 `String name` , `int age` , `int grade` 멤버 변수를 가지고 있다. 이 변수를 사용하는 데 필요한 메모리 공간도 함께 확보한다.

 

3. 참조값 보관

student1 = x001; // Student 인스턴스 참조값 보관
  • 객체를 생성하면 자바는 메모리 어딘가에 있는 이 객체에 접근할 수 있는 참조값(주소)(`x001`)을 반환한다.
  • `new` 키워드를 통해 객체가 생성되고 나면 참조값을 반환한다. 앞서 선언한 변수인 `Student student1` 에 생성된 객체의 참조값(`x001`)을 보관한다.

 

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

객체를 생성하는 `new Student()` 코드 자체에는 아무런 이름이 없다. 이 코드는 단순히 `Student` 클래스를 기반으로 메모리에 실제 객체를 만드는 것이다. 따라서 생성한 객체에 접근할 수 있는 방법이 필요하다.

이런 이유로 객체를 생성할 때 반환되는 참조값을 어딘가에 보관해두어야 한다. 앞서 `Student student1` 변수에 참조값(`x001`)을 저장해두었으므로 저장한 참조값(`x001`)을 통해서 실제 메모리에 존재하는 객체에 접근할 수 있다.

 

정리

Student student1 = new Student(); // 1. Student 객체 생성
Student student1 = x001; // 2. new Student()의 결과로 x001 참조값 반환
student1 = x001; // 3. 최종 결과

 

참조값을 확인하기 -> 객체를 담고 있는 변수를 출력

System.out.println(student1);
System.out.println(student2);

 

출력 결과

class1.Student@7a81197d
class1.Student@2f2c9b19

@ 앞은 패키지 + 클래스 정보를 뜻하고, @ 뒤에 16진수는 참조값을 뜻한다.

 

 

2. 객체 사용

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

//객체 값 대입
student1.name = "학생1";
student1.age = 15;
student1.grade = 90;

//객체 값 사용
System.out.println("이름:" + student1.name + " 나이:" + student1.age + " 성적:" + student1.grade);

 

객체 참조 그림

 

객체에 값 대입

객체가 가지고 있는 멤버 변수(name ,age ,grade)에 값을 대입하려면 먼저 객체에 접근해야 한다.

객체에 접근하려면 `.` (점, dot) 키워드를 사용하면 된다. 이 키워드는 변수(student1)에 들어있는 참조값(x001)을 읽어서 메모리에 존재하는 객체에 접근한다.

 

student1.name="학생1" // 1. student1 객체의 name 멤버 변수에 값 대입
x001.name="학생1" // 2.변수에 있는 참조값을 통해 실제 객체에 접근, 해당 객체의 name 멤버 변수에 값 대입

`student1.`(dot)이라고 하면 `student1` 변수가 가지고 있는 참조값을 통해 실제 객체에 접근한다. `student1` 은 `x001` 이라는 참조값을 가지고 있으므로 `x001` 위치에 있는 `Student` 객체에 접근한다.

 

`student1.name="학생1"` 코드 실행 전

 

`student1.name="학생1"` 코드 실행 후

 

객체 값 읽기

`.` (점, dot) 키워드를 통해 참조값을 사용해서 객체에 접근한 다음에 원하는 작업을 하면 된다.

//1. 객체 값 읽기
System.out.println("이름:" + student1.name);
//2. 변수에 있는 참조값을 통해 실제 객체에 접근하고, name 멤버 변수에 접근한다.
System.out.println("이름:" + x001.name);
//3. 객체의 멤버 변수의 값을 읽어옴
System.out.println("이름:" + "학생1");

 

 

`x001` 에 있는 `Student` 인스턴스의 `name` 멤버 변수는 "학생1"이라는 값을 가지고 있다. 이 값을 읽어서 사용한다.

 

 

3. 클래스, 객체, 인스턴스 정리

클래스 - Class

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

ex) 설계도: 자동차 설계도를 생각해보자. 자동차 설계도는 자동차가 아니다. 설계도는 실제 존재하는 것이 아니라 개념으로만 있는 것이다. 설계도를 통해 생산한 실제 존재하는 흰색 테슬라 모델 Y 자동차를 객체 또는 인스턴스라 한다.

 

객체 - Object

객체는 클래스에서 정의한 속성과 기능을 가진 실체이다. 객체는 서로 독립적인 상태를 가진다.

ex) 위 코드에서 student1 은 학생1의 속성을 가지는 객체이고, student2 는 학생2의 속성을 가지는 객체이 다. student1 과 student2 는 같은 클래스에서 만들어졌지만, 서로 다른 객체이다.

 

인스턴스 - Instance

인스턴스는 특정 클래스로부터 생성된 객체를 의미한다. 인스턴스는 주로 객체가 어떤 클래스에 속해 있는지 강조할 때 사용한다. ex) student1 객체는 Student 클래스의 인스턴스다.

 

객체 vs 인스턴스

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

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

ex) student1 은 객체이지만, 이 객체가 Student 클래스로부터 생성된다는 점을 명확히 하기 위해 student1 을 Student 의 인스턴스라고 부른다.

하지만 둘다 클래스에서 나온 실체라는 핵심 의미는 같기 때문에 보통 둘을 구분하지 않고 사용한다.

 

 

4. 배열 도입

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

`Student` 클래스를 사용한 변수들도 `Student` 타입이기 때문에 학생도 배열을 사용해서 하나의 데이터 구조로 묶어서 관리할 수 있다.

`Student` 타입을 사용하는 배열을 도입한다.

 

ClassStart4

package class1;

public class ClassStart4 {

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

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

        Student[] students = new Student[2];
        students[0] = student1;
        students[1] = student2;

        System.out.println("이름:" + students[0].name + " 나이:" + students[0].age + " 성적:" + students[0].grade);
        System.out.println("이름:" + students[1].name + " 나이:" + students[1].age + " 성적:" + students[1].grade);
    }
}

 

코드를 분석해보자.

Student student1 = new Student(); // 인스턴스 생성
student1.name = "학생1"; // 필요한 값 채움
student1.age = 15;
student1.grade = 90;

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

`Student` 클래스 기반으로 `student1`, `student2` 인스턴스를 생성하고, 필요한 값을 채워둔다.

 

인스턴스 생성 그림

 

배열에 참조값 대입

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

Student[] students = new Student[2];

 

  • `Student` 타입의 변수는 `Student` 인스턴스의 참조값을 보관한다. `Student` 배열의 각각의 항목도 `Student` 타입의 변수일 뿐이다. 따라서 `Student` 타입의 참조값을 보관한다.
  • 배열에는 아직 참조값을 대입하지 않았기 때문에 참조값이 없다는 의미의 `null` 값으로 초기화 된다.

 

다음 배열에 객체를 보관한다.

students[0] = student1;
students[1] = student2;

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

 

[중요] 자바에서 대입은 항상 변수에 들어 있는 값을 복사해서 전달한다.

자바에서 변수의 대입(`=`)은 모두 변수에 들어있는 값을 복사해서 전달하는 것이다. 

`student1`, `student2`에는 참조값이 보관되어 있다. 그래서 이 값을 복사해서 왼쪽에 있는 배열에 전달한다. 따라서 기존 `student1`, `student2`에 들어있던 참조값은 그대로 유지된다.

 

주의!

변수에는 인스턴스 자체가 들어있는 것이 아니라 인스턴스 위치를 가리키는 참조값이 들어있을 뿐이다. 따라서 대입(`=`) 시에 인스턴스가 복사되는 것이 아니라 참조값만 복사된다.

 

배열에 참조값을 대입한 이후 최종 그림

 

배열에 들어있는 객체 사용

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

 

학생1 예제

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");

 

 

배열 도입 - 리펙토링

ClassStart5

package class1;

public class ClassStart5 {

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

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

        Student[] students = new Student[]{student1, student2};

        for (int i = 0; i < students.length; i++) {
            System.out.println("이름:" + students[i].name + " 나이:" + students[i].age + " 성적:" + students[i].grade);
        }
    }
}

 

배열 선언 최적화

직접 정의한 `Student` 타입도 일반적인 변수와 동일하게 배열을 생성할 때 포함할 수 있다.

Student[] students = new Student[]{student1, student2};

 

생성과 선언을 동시에 하는 경우 다음과 같이 더 최적화 할 수 있다.

Student[] student2 = {student1, student2};

 

for문 최적화

배열을 사용한 덕분에 for문을 사용해서 반복 작업을 깔끔하게 처리할 수 있다.

 

for문 도입

for (int i = 0; i < students.length; i++) {
    System.out.println("이름:" + students[i].name + " 나이:" + students[i].age + " 성적:" + students[i].grade);
}

 

for문 - 반복 요소를 변수에 담아서 처리하기

for (int i = 0; i < students.length; i++) {
    Student s = students[i];
    System.out.println("이름:" + s.name + " 나이:" + s.age + " 성적:" + s.grade);
}

 

향상된 for문(Enhanced For Loop)

for (Student s : students) {
    System.out.println("이름:" + s.name + " 나이:" + s.age + " 성적:" + s.grade);
}

단축키: iter

 

 

5. 문제와 풀이

문제: 영화 리뷰 관리하기1

문제 설명

당신은 영화 리뷰 정보를 관리하려고 한다. 먼저, 영화 리뷰 정보를 담을 수 있는 `MovieReview` 클래스를 만들어보자.

 

요구 사항

1. `MovieReview` 클래스는 다음과 같은 멤버 변수를 포함해야 한다.

  • 영화 제목 ( title )
  • 리뷰 내용 ( review )

2. `MovieReviewMain` 클래스 안에 `main()` 메서드를 포함하여, 영화 리뷰 정보를 선언하고 출력하자.

 

예시 코드 구조

public class MovieReview {
    String title;
    String review;
}
public class MovieReviewMain {
    public static void main(String[] args) {
        // 영화 리뷰 정보 선언
        // 영화 리뷰 정보 출력
    }
}

 

출력 예시

영화 제목: 인셉션, 리뷰: 인생은 무한 루프
영화 제목: 어바웃 타임, 리뷰: 인생 시간 영화!

 

풀이 코드

package class1.ex;

public class MovieReviewMain {
    public static void main(String[] args) {
        // 영화 리뷰 정보 선언
        MovieReview movie1 = new MovieReview();
        movie1.title = "인셉션";
        movie1.review = "인생은 무한 루프";

        MovieReview movie2 = new MovieReview();
        movie2.title = "어바웃 타임";
        movie2.review = "인생 시간 영화!";

        // 영화 리뷰 정보 출력
        System.out.println("영화 제목: " + movie1.title + ", 리뷰: " + movie1.review);
        System.out.println("영화 제목: " + movie2.title + ", 리뷰: " + movie2.review);

    }
}

 

 

문제: 영화 리뷰 관리하기 2

기존 문제에 배열을 도입하고, 영화 리뷰를 배열에 관리하자.

리뷰를 출력할 때 배열과 `for` 문을 사용해서 `System.out.println` 을 한번만 사용하자.

 

풀이 코드

package class1.ex;

public class MovieReviewMain2 {
    public static void main(String[] args) {
        MovieReview[] movies = new MovieReview[2];

        MovieReview movie1 = new MovieReview();
        movie1.title = "인셉션";
        movie1.review = "인생은 무한 루프";

        MovieReview movie2 = new MovieReview();
        movie2.title = "어바웃 타임";
        movie2.review = "인생 시간 영화!";

        movies[0] = movie1;
        movies[1] = movie2;

        for(MovieReview review : movies) {
            System.out.println("영화 제목: " + review.title + ", 리뷰: " + review.review);
        }

    }
}

 

 

문제: 상품 주문 시스템 개발

문제 설명

당신은 온라인 상점의 주문 관리 시스템을 만들려고 한다.

먼저, 상품 주문 정보를 담을 수 있는 `ProductOrder` 클래스를 만들어보자.

 

요구 사항

1. `ProductOrder` 클래스는 다음과 같은 멤버 변수를 포함해야 한다.

  • 상품명 ( productName )
  • 가격 ( price )
  • 주문 수량 ( quantity )

2. `ProductOrderMain` 클래스 안에 `main()` 메서드를 포함하여, 여러 상품의 주문 정보를 배열로 관리하고, 그 정보들을 출력하고, 최종 결제 금액을 계산하여 출력하자.

3. 출력 예시와 같도록 출력하면 된다.

 

예시 코드 구조

public class ProductOrder {
    String productName; // 상품명
    int price; // 가격
    int quantity; // 주문 수량
}
public class ProductOrderMain {
    public static void main(String[] args) {
        // 여러 상품의 주문 정보를 담는 배열 생성
        // 상품 주문 정보를 `ProductOrder` 타입의 변수로 받아 저장
        // 상품 주문 정보와 최종 금액 출력
    }
}

 

출력 예시

상품명: 두부, 가격: 2000, 수량: 2
상품명: 김치, 가격: 5000, 수량: 1
상품명: 콜라, 가격: 1500, 수량: 2
총 결제 금액: 12000

 

풀이 코드

package class1.ex;

public class ProductOrderMain {
    public static void main(String[] args) {
        // 여러 상품의 주문 정보를 담는 배열 생성
        ProductOrder[] orders = new ProductOrder[3];

        // 상품 주문 정보를 `ProductOrder` 타입의 변수로 받아 저장
        ProductOrder order1 = new ProductOrder();
        order1.productName = "두부";
        order1.price = 2000;
        order1.quantity = 2;
        orders[0] = order1;

        ProductOrder order2 = new ProductOrder();
        order2.productName = "김치";
        order2.price = 5000;
        order2.quantity = 1;
        orders[1] = order2;

        ProductOrder order3 = new ProductOrder();
        order3.productName = "콜라";
        order3.price = 1500;
        order3.quantity = 2;
        orders[2] = order3;

        // 상품 주문 정보와 최종 금액 출력
        int total = 0;
        for(ProductOrder o : orders) {
            total += o.price * o.quantity;
            System.out.println("상품명: " + o.productName + ", 가격: " + o.price + ", 수량: " + o.price);
        }
        System.out.println("총 결제 금액: " + total);
    }
}
반응형

'Course > Java' 카테고리의 다른 글

[java-basic] 5. 패키지  (0) 2024.12.20
[java-basic] 4. 생성자  (1) 2024.12.17
[java-basic] 3. 객체 지향 프로그래밍  (0) 2024.12.16
[java-basic] 2. 기본형과 참조형  (0) 2024.12.11

댓글