✅ 클래스와 객체
클래스란 ‘객체를 정의해 놓은 것’, 또는 ‘객체의 설계도, 틀’이라고 할 수 있습니다.
클래스는 관련된 데이터와 메서드(기능)의 집합으로, 객체를 생성하는데 사용됩니다. 객체는 클래스의 인스턴스(실체)로, 클래스에 정의된 데이터와 메서드를 사용할 수 있습니다. 즉, 객체를 만들기 위해 구성하는 틀이라고 생각하면 됩니다.
현실 세계의 자전거를 빗대어 클래스에 대해 알아보겠습니다.
현실 세계의 자전거는 아래와 같은 데이터를 가지고 있고, 특정한 동작을 수행합니다.
🔻클래스 : 자전거 (Bicycle)
—속성 (데이터):
- 색깔 (color): 빨강, 파랑, 노랑 등
- 브랜드 (brand): Giant, Trek, Cannondale 등
- 가격 (price): 정수나 실수로 표현되는 가격
- 속도 (speed): 정수로 표현되는 속도
- 기어 (gear): 정수로 표현되는 기어 수
—동작 (메서드):
- 가속하기 (accelerate): 자전거의 속도를 빠르게 증가시킵니다.
- 감속하기 (decelerate): 자전거의 속도를 느리게 감소시킵니다.
- 정지하기 (stop): 자전거를 완전히 멈춥니다.
- 변속하기 (changeGear): 자전거의 기어를 변경합니다.
클래스는 객체(실제로 존재하는 것)을 만들기 위한 일종의 틀입니다. 그렇다면 클래스를 통해 만들어진 실제로 존재하는 객체를 한 번 살펴보겠습니다.
객체란 ‘실제로 존재하는 것, 사물 또는 개념’이라고 할 수 있습니다. 프로그래밍에서의 객체는 클래스에 정의된 내용대로 메모리에 생성된 것을 뜻합니다.
🔻객체1: 자전거1 (Bicycle)
- color: 빨강
- brand: Giant
- price: 500,000
- speed: 0
- gear: 1
- 동작(메소드) : 가속, 감속, 정지, 변속
자전거 클래스의 틀을 가지고 만들어진 객체는 위와 같은 데이터와 클래스에서 정의한 특정한 기능을 가지고 있습니다. 객체는 클래스로부터 생성되었으며, 속성(데이터)와 동작(메서드)을 공유합니다. 자전거1은 속도를 가속하거나 감속할 수 있으며, 기어를 변경할 수도 있습니다. 이것을 실제 코드로 구현해 보겠습니다.
- 클래스 정의
public class Bicycle { //데이터를 정의함. public String color; //색깔 public String brand; //브랜드 public double price; //가격 public int speed; //속도 public int gear; //기어 // Constructor 생성자 public Bicycle(String color, String brand, double price) { this.color = color; this.brand = brand; this.price = price; this.speed = 0; this.gear = 1; } //특정한 동작(Method), 기능을 수행함. value는 임의의 값. public void accelerate(int value) { //가속 speed += value; System.out.println("Accelerating. Current speed: " + speed); } public void decelerate(int value) { //감속 speed -= value; System.out.println("Decelerating. Current speed: " + speed); } public void stop() { //정지 speed = 0; System.out.println("Stopping. Bicycle is now at rest."); } public void changeGear(int newGear) { //변속 gear = newGear; System.out.println("Changing gear to: " + gear); } }
컴퓨터가 저장할 수 있는 데이터의 타입에 맞게 데이터를 저장할 수 있도록 변수를 선언합니다. 특정한 동작을 수행하는 메소드를 정의하여, 특정한 값에 따라 상태가 변하는 것을 속도라는 변수에 저장할 수 있도록 기능을 구현했습니다. 또한 기능(메소드)가 잘 실행되었는지 확인하기 위해 콘솔창에 출력되도록 했습니다. 생성자는 클래스를 통해 객체를 생성할 때 초기의 값을 어떻게 저장할지 구현하는 것입니다.
이를 통해 어떻게 코드로 객체를 생성하는지 살펴보겠습니다.
- 객체의 생성과 사용
public class Main { public static void main(String[] args) { Bicycle bicycle1 = new Bicycle("빨강", "Giant", 5000); // 객체의 속성(데이터) 출력 System.out.println("Color: " + bicycle1.getColor()); System.out.println("Brand: " + bicycle1.getBrand()); System.out.println("Price: " + bicycle1.getPrice()); // 객체의 동작 실행 bicycle1.accelerate(20); bicycle1.changeGear(3); bicycle1.decelerate(10); bicycle1.stop(); } }
자전거 1은 색깔이 빨강색이고, 브랜드는 Giant이며, 가격은 5000입니다. 클래스라는 틀을 가지고 자전거 1의 데이터를 가진 객체를 생성했습니다. 객체의 속성(데이터)를 출력하고, 객체가 특정 동작을 실행(메소드 실행)했을 때의 결과를 확인해보겠습니다.
Color: 빨강 Brand: Giant Price: 5000 Accelerating. Current speed: 20 Changing gear to: 3 Decelerating. Current speed: 10 Stopping. Bicycle is now at rest.
색깔이 빨강이며, 브랜드는 Giant, 가격이 5000인 자전거 1이, 20의 가속을 했을 때, 기어를 3으로 바꾸었을 때, 10의 감속을 했을 때, 정지했을 때 각각의 기능이 실행되었음을 출력되었습니다.
👉 클래스를 통해 객체를 생성하는 이유는 설계도를 통해서 제품을 만드는 이유와 같습니다. 하나의 설계도만 잘 만들어 놓으면 제품을 만드는 일이 쉬워지기 때문입니다. 제품의 색깔, 브랜드, 가격이 달라도 동일한 기능을 수행하는 자전거를 손쉽게 만들 수 있습니다.
✅ 객체의 구성요소 -속성과 기능
객체는 다수의 속성과 다수의 기능을 가진 집합이라고 할 수 있습니다. 객체가 가지고 있는 속성과 기능을 그 객체의 멤버(구성원, member)라고 합니다. 또한 아래와 같이 같은 뜻의 여러가지 용어가 존재합니다.
- 속성(property) == 멤버변수(member variable), 특성(attribute), 필드(field), 상태(state)
- 기능(function) == 멤버메소드(method), 함수(function), 행위(behavior)
자전거라는 클래스가 있다고 하였을 때 멤버를 살펴보겠습니다.
클래스 | 자전거 |
---|---|
속성 | 색깔, 브랜드, 가격, 속도, 기어 |
기능 | 가속, 감속, 정지, 변속 |
➡️이를 코드로 보면 다음과 같습니다.
public class Bicycle {
//데이터를 정의함.
public String color; //색깔
public String brand; //브랜드
public double price; //가격
public int speed; //속도
public int gear; //기어
// Constructor 생성자
public Bicycle(String color, String brand, double price) {
this.color = color;
this.brand = brand;
this.price = price;
this.speed = 0;
this.gear = 1;
}
//특정한 동작(Method), 기능을 수행함. value는 임의의 값.
public void accelerate(int value) { //가속
speed += value;
System.out.println("Accelerating. Current speed: " + speed);
}
public void decelerate(int value) { //감속
speed -= value;
System.out.println("Decelerating. Current speed: " + speed);
}
public void stop() { //정지
speed = 0;
System.out.println("Stopping. Bicycle is now at rest.");
}
public void changeGear(int newGear) { //변속
gear = newGear;
System.out.println("Changing gear to: " + gear);
}
}
✅ 객체의 생성과 사용, 참조변수
객체를 생성할 때는 보통 new 키워드를 사용해서 생성합니다. 객체를 생성하고 사용할 때 참조 변수를 사용하는게 이것이 무엇인지 살펴보겠습니다.
- 객체의 생성과 사용
public class Main { public static void main(String[] args) { Bicycle bicycle1 = new Bicycle("빨강", "Giant", 5000); // 객체의 속성(데이터) 출력 System.out.println("Color: " + bicycle1.getColor()); System.out.println("Brand: " + bicycle1.getBrand()); System.out.println("Price: " + bicycle1.getPrice()); // 객체의 동작 실행 bicycle1.accelerate(20); bicycle1.changeGear(3); bicycle1.decelerate(10); bicycle1.stop(); } }
- Bicycle bicycle1;
Bicycle
클래스 타입의 참조변수 bicycle1을 선언했습니다. 선언만 했을 경우에 메모리 상에 참조변수 bicycle1이 참조할 수 있는 특정 메모리 공간이 생성됩니다.
- Bicycle bicycle1 = new Bicycle();
new 연산자를 통해 Bicycle 클래스의 인스턴스가 메모리의 빈 공간에 생성됩니다. 메모리의 존재하는 인스턴스를 가리키는 주소를 임의로 0x100이라고 가정해보겠습니다. 현재 코드는 인스턴스만 생성되었을 뿐 초기화하지 않았으므로 각 타입에 기본값으로 자동으로 초기화가 됩니다.( String = null, int = 0 )
그 다음에는 대입 연산자 = 에 의해서 bicycle 참조 변수는 Bicycle의 인스턴스의 주소값 0x100을 저장하게 됩니다.
참조 변수의 저장된 메모리의 주소값을 통해서 Bicycle 클래스의 인스턴스에 접근할 수 있게 되었습니다. 인스턴스를 다루기 위해서는 참조 변수가 반드시 필요하며, 참조 변수를 통해 참조하지 않는 메모리 상의 인스턴스는 가비지 콜렉션의 의해서 제거됩니다.
인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야 한다.
- 위의 코드와 같이 생성자를 통해서 초기화 한 경우
생성자를 통해서 초기화한 경우에는 아래와 같이 값이 변경되어 있을 것입니다.
- Bicycle bicycle1;
- 참조 변수에 참조 변수 대입할 경우
하나의 참조 변수에 다른 참조 변수를 대입 연산자 =을 통해서 대입하면 어떻게 될까요? 아래와 같이 두 개의 인스턴스를 생성하고 참조 변수에 참조 변수를 대입해 보겠습니다.
public class Main { public static void main(String[] args) { Bicycle bicycle1 = new Bicycle(); Bicycle bicycle2 = new Bicycle(); bicycle1 = bicycle2;
- 두 개의 참조 변수와 두 개의 인스턴스가 생성됩니다. 각각의 참조 변수는 각각의 인스턴스를 참조합니다. 각각의 참조 변수에는 참조하는 인스턴스의 메모리 주소가 저장되게 됩니다.
- 대입 연산자의 의해서 bicycle2가 bicycle1을 참조하게 될 경우, bicycle2에는 bicycle1이 가지고 있는 인스턴스의 주소값을 저장하게 됩니다. bicycle1과 bicycle2가 동일한 인스턴스를 참조하게 되는 것입니다. bicycle2가 참조하고 있던 메모리 주소 0x200에 해당하는 인스턴스는 더 이상 참조하는 변수가 없기 때문에 가비지 콜렉션에 의해서 제거됩니다.
👉 참조 변수 하나에는 하나의 인스터스의 주소 값만 저장될 수 있습니다. 여러 개의 참조 변수가 하나의 인스턴스를 동일하게 참조하는 것은 가능하지만, 하나의 참조 변수가 여러 개의 인스턴스를 동시에 참조할 수는 없습니다.
- 두 개의 참조 변수와 두 개의 인스턴스가 생성됩니다. 각각의 참조 변수는 각각의 인스턴스를 참조합니다. 각각의 참조 변수에는 참조하는 인스턴스의 메모리 주소가 저장되게 됩니다.
Uploaded by N2T