[Java] 클래스와 객체

김용준·2022년 9월 23일
0

Java Basic

목록 보기
14/22

클래스란?

  • 객체의 속성과 기능을 정의해둔 설계도다.
  • 필드, 생성자, 메소드로 구성되어 있다.
  • 필드가 속성, 메소드가 기능에 해당한다.
  • 생성자는 객체 생성 직후에 실행되는 메소드다.
  • 클래스로부터 객체를 생성하는 것을 '클래스의 인스턴스화'라고 한다.
  • 클래스명의 첫 문자는 대문자로 작성해야 한다.

클래스에 대한 이해를 돕기 위해 프로그래밍 언어에서 데이터 저장형태의 발전과정을 알아보자.

  1. 하나의 값을 저장하기 위한 '변수'
    int score = 50
  2. 동일한 타입의 값 여러 개를 저장하기 위한 '배열'
    int[] scores = new int[10]
  3. 다양한 타입의 값 여러 개와 관련된 기능을 정의한 '클래스'
    public class Student { ... }

이처럼 다루는 데이터가 복잡해짐에 따라 보다 효율적으로 데이터를 다루기 위해 '클래스'가 등장했다. 변수나 배열에 데이터 타입이 존재하는 것처럼 클래스에도 타입이 있다. 그런데 클래스는 다루고자하는 값들과 기능을 사용자가 직접 정의하므로 클래스가 곧 '사용자 정의 타입(user-defined type)'이다.

구성요소

접근제한자 class 클래스명 {

필드 정의
생성자 정의(생략 가능)
메소드 정의

}
  • 필드 (Field)
    • 객체의 고유한 속성을 나타낸다.
    • 초기화를 하지 않으면 해당 자료형의 기본값으로 초기화된다.
    • 생성자와 메소드 전체에서 사용 가능하다.
    • 객체가 소멸되지 않는 한 객체와 함께 유지된다.
  • 생성자 (Constructor)
    • 객체 생성시 초기화를 담당한다.
    • 반드시 클래스명과 동일한 이름을 갖고, 반환타입이 없다.
    • new연산자로 호출되는 특별한 메소드다.
    • 객체를 생성할 때만 호출할 수있다.
  • 메소드 (Method)
    • 객체의 고유한 기능을 담당한다.
    • 이름을 가진 실행문의 블록이다.
    • 메소드를 호출하면 블록 내 모든 실행문이 수행된다.
    • 메소드를 호출하는 측으로부터 데이터를 전달 받을 수 있고, 실행 후 결과값을 호출한 측에 반환할 수 있다.
    • 메소드는 선언부와 구현부로 구성되어 있다.

다음은 학생의 이름과 성적정보, 그리고 성적정보를 이용해 평균점수를 계산하는 메소드를 정의한 클래스다.

// 클래스 외부에서 접근 가능한 Student클래스를 정의한다. 
public class Student {
	
    // 필드, 학생의 속성들을 정의한다.
	String name;
	int korScore;
	int engScore;
    int mathScore;
    
    // 메소드, 세 과목을 이용해 평균을 계산하는 기능을 정의한다.
    public void processScore() {
    	double average = (korScore + engScore + mathScore)/3.0
	}

객체란?

  • 클래스에서 정의한 것을 바탕으로 실제 메모리에 할당되는 데이터이다.
  • 모든 객체는 주소값을 갖고 있으며 객체의 참조변수가 그 주소값을 저장한다.
  • 참조변수에 저장된 주소값을 통해 원하는 객체에 접근할 수 있다.

일반적인 변수가 데이터 타입을 갖는 것처럼 참조변수도 타입을 갖는다. 참조변수의 타입은 그 참조변수가 참조하는 객체의 클래스다.
예를 들어 Student클래스로 생성한 객체의 주소값을 저장하는 참조변수 student가 있다면, student의 타입은 Student이다.

객체 생성

new연산자와 클래스명을 이용해서 객체를 생성한다. 생성된 객체의 주소값은 참조변수에 대입된다.

클래스명 참조변수;				// 참조변수 선언
참조변수 = new 클래스명();		// 객체 생성

클래스명 참조변수 = new 클래스명();		// 참조변수 선언과 동시에 객체 생성

Student student = new Student()

Student
    * Student클래스로 생성한 객체를 참조하는 변수의 타입을 정의한다.

student
	* 참조변수의 이름을 student로 지정한다.
	* Student클래스로 생성한 객체의 주소값을 저장한다.

new
	* 객체를 생성하는 '연산자'이다.
    * 메모리의 Method영역에 클래스를 로딩하고, Heap영역에 객체를 생성한다.
    * Heap영역에 생성된 객체의 주소값을 반환한다.
    * 반환된 주소값을 참조변수 student에 대입한다.

Student()
	* 생성자 메소드다. 클래스 이름과 동일해야만 한다.
    * 객체 생성 직후 자동으로 실행된다.
public class StudentApp {

	public static void main(String[] args) {
		
        // Student클래스로 객체를 생성한 후, 그 객체의 주소값을 참조변수에 저장한다.
		Student student1 = new Student();
        Student student2 = new Student();
        Student student3 = new Student();
        
        // 객체를 생성하면 객체를 고유하게 식별할 수 있는 '해쉬코드'가 생성되고 모든 객체는 이러한 기능을 갖고 있다.
		System.out.println(student1);
        System.out.println(student2);
        System.out.println(student3);
	}
}

객체를 생성하는 코드 Student student = new Student()가 실행되는 과정을 정리하면 다음과 같다.

  1. new연산자는 생성자와 동일한 이름의 클래스를 Method영역에 로딩한다.
  2. 로딩된 Student클래스로부터 Heap영역에 객체를 생성한다.
  3. 생성자Student()를 실행해서 객체를 초기화한다.
  4. 객체의 주소값을 반환한다.
  5. 반환된 주소값을 Student타입의 참조변수 student에 대입한다.

객체의 속성과 기능

객체를 생성하면 클래스로부터 정의된 객체의 변수와 메소드를 사용할 수 있다. 생성된 객체의 변수와 메소드에 접근하려면 반드시 참조변수에 객체의 주소값을 저장해두어야 한다.
생성된 객체의 속성과 기능을 각각 '인스턴스 변수'와 '인스턴스 메소드'라고 한다. 또한, 인스턴스 메소드를 사용하기 위해 전달해주어야 하는 값을 '매개변수'라 하고 실제로 매개변수에 전달된 값을 '인자'라고 한다.

// 생성된 객체의 속성에 값 저장하기
참조변수.필드명 = 값;

// 생성된 객체의 속성에 저장된 값을 조회해서 변수에 저장하기
자료형 변수명 = 참조변수.필드명

// 생성된 객체의 기능 사용하기
참조변수.메소드명();

// 생성된 객체의 기능을 실행할 때 필요한 값 전달하기
참조변수.메소드명(매개변수1, 매개변수2);

// 생성된 객체의 기능을 실행하고, 결과값을 반환받기
자료형 변수명 = 참조변수.메소드명(매개변수1, 매개변수2);

다음은 학생 정보를 다루는 클래스를 정의하고, 학생 객체를 생성하여 그 속성과 기능을 이용하는 예제이다.

// Student클래스를 정의한다.
// 4개의 필드와 필드에 저장된 값을 출력하는 메소드를 갖고있다.
public class Student {
	
    // 필드 정의
	String name;
	int korScore;
	int engScore;
	int mathScore;
	
    // 메소드 정의, 필드에 저장된 값을 출력한다.
	public void display() {
		System.out.println("[" + name + "]의 성적");
		System.out.println("국어점수: " + korScore);
		System.out.println("영어점수: " + engScore);
		System.out.println("수학점수: " + mathScore);
	}
}
// Student객체를 생성하고 그 변수와 메소드를 활용한다.
public class StudentApp {

	public static void main(String[] args) {
		
        // Student클래스로부터 객체 생성
		Student student = new Student();
		
        // student객체의 인스턴스 변수에 값 저장
		student.name = "OOO";
		student.korScore = 96;
		student.engScore = 87;
		student.mathScore = 72;
		
        // student객체의 인스턴스 메소드 실행
		student.display();
	}
}
출력

[OOO]의 성적
국어점수: 96
영어점수: 87
수학점수: 72

객체를 필드로 갖는 객체

클래스를 정의할 때 기본형 변수를 필드로 정의했다. 참조형 변수 또한 필드로 정의할 수 있다. 즉, 객체의 멤버변수로서 객체도 가능하다는 의미이다. 물론 참조형 변수이므로 배열도 가능하다.

// 학생을 표현하는 클래스, Score객체를 필드로 가진다.
public class Student {
	String name;
	int age;
	Score score;
}
// 학생의 과목별 성적을 표현하는 클래스.
public class Score {
	int korScore;
	int engScore;
	int mathScore;
}
public class App {

	public static void main(String[] args) {
		
		Student student = new Student();
		student.name = "OOO";
		student.age = 24;
		
        // Score객체를 생성해서 멤버변수에 과목별 점수를 대입한다.
		Score subjectScore = new Score();
		subjectScore.korScore = 100;
		subjectScore.engScore = 90;
		subjectScore.mathScore = 80;
		
        // Score객체를 Student객체의 멤버변수로 대입한다.
		student.score = subjectScore;
		
		System.out.println("이름: " + student.name);
		System.out.println("나이: " + student.age);
		System.out.println("국어점수: " + student.score.korScore);
		System.out.println("영어점수: " + student.score.engScore);
		System.out.println("수학점수: " + student.score.mathScore);
	}
}
출력

이름: OOO
나이: 24
국어점수: 100
영어점수: 90
수학점수: 80

객체의 변수가 가지는 기본값

메소드 내에서 변수를 선언하고 초기화를 하지 않으면 알 수 없는 값(쓰레기값)이 저장되어 있기 때문에 에러가 발생한다. 그러나 객체를 생성한 후, 멤버변수는 기본값이 저장되어 있다. 그래서 초기화하지 않아도 에러가 발생하지 않는다. 자료형에 따른 기본값은 아래 표와 같다.

자료형기본값
byte0
short0
int0
long0L
float0.0f
double0.0d
booleanfalse
char'\u0000'
참조형 변수
(String포함)
null
profile
차선이 모여 최선이 된다.

0개의 댓글