클래스 (Class) 클래스는 객체를 생성하기 위한 템플릿 또는 설계도와 같다. 클래스는 객체의 기본 형태를 정의하며, 해당 객체의 상태를 나타내는 필드(변수)와 상태를 조작할 수 있는 메서드(함수)를 포함한다. 클래스는 데이터와 행위를 하나로 묶는 캡슐화의 주요 단위이다. 예: 자동차 설계도에서 자동차의 특성(속성)과 동작(메서드)을 정의한다.
객체 (Object) 객체는 클래스에 기반하여 생성된 실체이다. 실제 프로그램 내에서 메모리에 할당된 상태를 가지고 있는 실행 가능한 어떤 것을 말한다. 객체는 클래스의 인스턴스로도 불리며, 클래스에서 정의된 필드와 동일한 속성(상태)와 메서드(행위)를 가진다. 예: 자동차 설계도를 바탕으로 만들어진 실제 자동차.
인스턴스 (Instance) 인스턴스는 클래스로부터 생성된 객체를 의미한다. 기술적으로 보면, 객체와 인스턴스는 같은 것을 지칭한다. 그러나 '인스턴스'라는 용어는 주로 객체가 메모리에 할당되어 실제로 생성된 상태를 강조할 때 사용된다. 예: 특정 자동차 설계도로 만들어진 특정 자동차(인스턴스)가 실제로 도로 위를 달리고 있을 때, 우리는 그것을 인스턴스라고 부를 수 있다.
용어의 차이 - 클래스는 추상적인 개념으로, 객체의 공통적인 구조와 행동을 정의한 코드 블록이다. - 객체는 클래스의 정의를 통해 메모리에 할당된 구체적인 실체이다. - 인스턴스는 객체가 메모리에 할당되어 실제로 생성된 것을 강조하는, 객체와 동일한 실체를 다른 관점에서 부르는 용어이다. 간단히 말해, 클래스는 객체의 설계도이며, 객체는 설계도를 바탕으로 만들어진 실체이고, 인스턴스는 그 실체가 메모리 상에 할당된 것을 특히 강조하는 표현이다.
자바 코드로 작성해서 위 세 개를 구분해 보자.
class Car { // 클래스 정의: Car라는 이름의 클래스를 정의합니다. // 필드(상태): Car 클래스의 속성들을 정의합니다. String color; String manufacturer;
// 생성자: Car 객체를 생성할 때 초기 상태를 설정합니다. Car(String color, String manufacturer) { this.color = color; this.manufacturer = manufacturer; }
// 메서드(행위): Car 클래스의 객체가 수행할 수 있는 행동을 정의합니다. void drive() { System.out.println(this.color + " " + this.manufacturer + " is driving."); } }
public class Main { public static void main(String[] args) { // 객체 생성: Car 클래스를 바탕으로 new 키워드를 사용해 객체를 생성합니다. Car myCar = new Car("Red", "Toyota");
// 인스턴스 확인: myCar는 Car 클래스의 인스턴스입니다. if (myCar instanceof Car) { System.out.println("myCar is an instance of Car class."); } } }
여기서 Car는 클래스이며 color와 manufacturer라는 상태(필드)와 drive()라는 행위(메서드)를 정의한다. main 메서드에서 new Car("Red", "Toyota")를 통해 Car 클래스의 객체를 생성하고, myCar라는 참조 변수에 할당한다. 이때 myCar는 Car 클래스의 객체이며, 동시에 Car 클래스의 인스턴스이다. instanceof 연산자를 사용하여 myCar가 실제로 Car 클래스의 인스턴스인지 확인할 수 있다. myCar.drive()를 호출함으로써 myCar 객체의 drive 메서드를 실행할 수 있다.
이 코드는 클래스를 정의하고, 그 클래스를 기반으로 객체를 생성하여 인스턴스를 만드는 과정을 보여준다. 한 마디로 클래스는 설계도, 객체는 설계도를 기반으로 생성된 실체, 인스턴스는 그 실체가 메모리에 할당되어 생성된 상태를 의미한다.
Information hiding(정보은닉) 에 대해 ------------------
정보은닉은 외부에서 데이터 접근을 제한한다는 개념이다. 언어적 측면에서 정보은닉은 접근 제한자를 통해 은닉의 정도를 구현할 수 있다. 따라서 클래스의 데이터 또는 메소드에 접근 제한자를 기술하여 외부에서 데이터 접근을 제한할 수 있다.
private : 자기 클래스 내부의 메소드에서만 접근 허용
default : 같은 패키지에 있는 객체만 접근 허용
protected : 같은 패키지에 있는 객체 또는 상속받은 자식 클래스에서 접근 허용
public : 모든 접근을 허용
정보은닉은 클래스의 핵심적인 데이터를 외부로부터 접근을 제한하여 데이터의 무결성을 보장해주고, 더 나아가 프로그램의 기능에 대한 신뢰성이 향상된다. - 데이터 무결성 보장 - 기능의 신뢰성 향상
참고 : 은닉화 vs 캡슐화
은닉화 : 불필요한 정보를 숨기는 것 ex) private int age; 캡슐화 : 데이터와 메소드를 하나로 묶는 것. ex) public int getAge(){ return age } 캡슐화는 은닉화를 구현하는 가장 기본적인 방법.
Encapsulation(캡슐화) : 캡슐화의 정의는 언어 측면과 기술 측면으로 정의할 수 있다.
- 언어 측면 : 객체의 속성(data fields)과 행위(methods)를 하나로 묶어져 있는 언어적 구조 - 기술 측면 : 일부 구현 내용을 외부에 감추어 은닉
이처럼 두 가지 측면은 다른 의미를 다루고 있지만, 모듈의 재사용성 향상이라는 하나의 방향성을 지향하고 있다.
먼저 언어적 측면으로는 흔히 클래스를 정의하고 내부에 데이터와 메소드를 정의하고, 정의된 클래스를 프로그램의 독립적인 단일 단위로 바라본다는 개념이다. 이는 클래스 기반 언어의 언어 구조 특징으로, 이를 캡슐화라 정의한다.
하지만 단순히 클래스 기반 언어의 구조 특징을 캡슐화라 정의할 수 없다. 캡슐화란 클래스 기반 언어의 구조적인 개념에 국한되어있지 않고, 다른 프로그래밍 언어에서도 캡슐화란 개념이 나오기 때문이다. 이러한 이유는 캡슐화란 일부 구현 기능의 은닉 정도를 제어한다는 측면으로 바라보는 개념이 있기 때문이다.
* 정보은닉 그리고 모듈화 : 이러한 캡슐화의 기술적 측면에선 정보은닉 개념을 통해 기능의 단순화라는 방향성에 초점을 두고 있다.