자바 클래스(Class) - 1

계리·2024년 1월 30일
0

실무에서 자주 사용하는 것들 위주로 개념을 다시 다져보려고 한다. 자바로 객체지향 프로그래밍을 하기 위해 가장 우선순위로 중요한 클래스에 대해 다시 학습을 해보기 위해 김영한님의 강의로 진행했다. 이 개념들이 왜 중요한지 문제를 통해 한번 살펴보려고 한다.


문제 : 학생 정보 출력 프로그램 만들기


요구사항
1. 첫 번째 학생의 이름은 "학생1", 나이는 15, 성적은 90입니다.
2. 두 번째 학생의 이름은 "학생2", 나이는 16, 성적은 80입니다.
3. 각 학생의 정보를 다음과 같은 형식으로 출력해야 합니다: "이름: [이름] 나이: [나이] 성적: [성적]"
4. 변수를 사용해서 학생 정보를 저장하고 변수를 사용해서 학생 정보를 출력해야 합니다.


예시 출력

이름: 학생1 나이: 15 성적: 90
이름: 학생2 나이: 16 성적: 80

예시 코드

package class1;

public class ClassStart1 {
	public static void main(String[] args) {
		String student1Name = "학생1";
        int student1Age = 15;
        int student1Grade = 90;
       
        String student2Name = "학생2";
        int student2Age = 16;
 		int student2Grade = 80;
 
 		System.out.println("이름:" + student1Name + " 나이:" + student1Age + " 성적:" + student1Grade);
 		System.out.println("이름:" + student2Name + " 나이:" + student2Age + " 성적:" + student2Grade);
	}
}

학생 성적에 대한 정보들을 출력하는 코드를 작성했다. 위 코드처럼 작성할 경우 학생이 늘어나면 늘어나는대로 계속해서 변수와 값을 넣어줘야 하고 출력문도 계속해서 추가를 해줘야 하는 상황이 발생한다.

그러면 계속해서 수정을 해야하고 입력하는 과정에서 오류가 발생하는 상황이 생길 수 있다.
유지보수 및 관리가 어려워 지는 상황이다.


해결방법1 - 배열 사용

package class1;

public class ClassStart2 {
	public static void main(String[] args) {
		 String[] studentNames = {"학생1", "학생2"};
		 int[] studentAges = {15, 16};
		 int[] studentGrades = {90, 80};
		 
		 for (int i = 0; i < studentNames.length; i++) {
			 System.out.println("이름:" + studentNames[i] + " 나이:" + studentAges[i] + " 성적:" + studentGrades[i]);
		 }
	}
}

배열을 통해 코드 수정을 줄이는데는 성공했지만 여전히 문제는 남아있다. 코드에 보면 배열로 학생에 대한 정보 데이터들이 들어있는데 값을 수정 해야하는 상황이 생기면 배열의 값을 직접 수정 해야한다.

배열에서 값을 변경할 때 예를 들어서 학생2에 대한 정보를 지우자고 했을 때 학생2에 대한 배열 인덱스들을 지워 줘야한다. 지금은 2명의 학생밖에 없기 때문에 손쉽게 지울 수 있지만 1000명의 학생 데이터가 있다고 예를 들었을 때 257번째 학생의 인덱스를 지워야 한다 했을 때 과연 studentNames배열, studentAges배열, studentGrade배열에 있는 257번째 학생의 인덱스를 정확하게 잘 지울 수 있을까?

1000명 중에 257번째 학생의 인덱스를 찾는거부터 일이 되고 그 데이터가 맞는지도 확인해야 되는 등 많은 시간이 낭비된다. 제대로 지우면 그나마 다행인데 잘못 지웠다가는 문제가 커질 수도 있다.


해결방안2 - 클래스 사용

package class1;

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

학생에 대한 개념을 묶어서 정의하기 위해 class 키워드를 이용해서 Student를 생성한다. 그리고 학생에 대한 정보 항목(또는 필드)들을 class안에서 생성 해준다.

이름 - String name
나이 - int age
성적 - int grade

자바에서 클래스 안에 선언된 변수들을 보통 멤버 변수(Member Variable) 또는 필드라고 한다.

멤버 변수 : 특정 클래스 안에 선언된 변수들을 말한다.
필드 : 보통 데이터 항목을 가리킬 때 사용하는 용어이다. 흔히 엑셀이나 데이터베이스 등에서 데이터의 각각의 항목을 필드라고 한다.


package class1;

public class ClassStart3 {

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

}

생성된 특정 클래스를 가져다가 사용해서 학생 정보 출력 프로그램을 만들었다.

  • 타입이라 하면 데이터의 종류나 형태를 나타낸다.
  • int라고 하면 정수형, String이라고 하면 문자 타입이라 한다.
  • 클래스도 int와 String 처럼 타입을 만들 수 있다.
  • 그래서 학생 타입 Student student1 이라고 선언을 한 것이다.
  • 사용자가 직접 정의하는 사용자 정의 타입을 만들려면 설계도가 필요한데 자바에서는 이 설계도가 클래스이다.
  • 설계도인 클래스를 사용해 실제 메모리에 만들어진 실체를 객체 또는 인스턴스라고 한다.
  • 클래스를 통해서 사용자가 원하는 타입의 클래스를 정의할 수 있다.

바로 위 소스를 가지고 간략하게 해석하면 학생(Student) 클래스를 가지고 학생1(student1), 학생2(student2) 객체 또는 인스턴스를 만든 것이다.


소스분석

  1. 변수 선언

Student student1

  • Student 타입의 student1 변수를 선언
  • student1 객체 또는 인스턴스를 생성할 준비가 됐다.

  1. 객체 선언

student1 = new Student();

  • new 연산자 + 클래스 명 + ()으로 사용
  • new 연산자를 통해 객체를 생성, new Student()는 Student 클래스를 기반으로 새로운 객체를 생성하라는 뜻이고 메모리에 실제 Student 객체(또는 인스턴스)를 생성한다.
  • Student 클래스는 String name, int age, int grade 멤버 변수들을 가지고 있어 이 변수들을 사용하는데 필요한 메모리 공간도 같이 확보한다.

  1. 참조값 보관

stduent1 = x001;

  • new 키워드를 통해 객체를 생성하면 자바는 메모리 어딘가에 해당 객체에 접근할 수 있는 참조 값(또는 주소 값, 예시 - x0001) 을 반환한다.
  • 그러면 student1에 생성된 객체의 참조 값을 보관한다.
  • Student student1 변수는 이제 메모리에 존재하는 실제 Student객체(또는 인스턴스)의 참조 값을 가지고 있다. 즉 실제 해당 객체를 접근하고 사용할 수 있다.

참조 값을 보관해야 하는 이유
객체를 생성하는 new Student() 코드 자체에는 아무런 이름이 없다. 이 코드는 단순히 Student 클래스를 기반으로 메모리에 실제 객체를 만드는 것이다. 따라서 생성한 객체에 접근할 수 있는 방법이 필요하다. 이런 이유로 객체를 생성할 때 반환되는 참조 값을 어딘가에 보관해두어야 한다. 앞서 Student studet1 변수에 참조 값을 저장해두었으므로 저장한 참조 값을 가지고 실제 메모리에 존재하는 객체에 접근할 수 있다. 단순히 객체를 생성하기 위한 코드이므로 객체를 생성해서 가져다가 사용하기 위해서는 연결고리가 필요하다. 그래서 생성된 객체에 참조 값(주소 값)을 보관한다. 주소 값이라고도 표현하는데 우리가 사는 집 주소를 생각하면 좀 더 이해하기 쉬울꺼라 생각이 든다. 친구 집을 찾아가기 위해 집 주소를 알아야되는 것처럼 해당 객체를 사용하기 위해서 해당 객체가 보관하고 있는 주소 값으로 찾아가 사용을 하는 것이다.

코드분석을 간단하게 풀어보면

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

학생2(student2)까지 생성하면 아래와 같이 Student 객체가 메모리에 2개 생성된다. 각각 객체의 참조 값이 다르기 때문에 구분이 가능하다.

다른 것을 확인하고 싶으면 아래 코드로 확인을 해보면 된다.

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

참고

  • 김영한의 실전 자바 기본편
profile
gyery

0개의 댓글