■클래스
앞서 우리는 객체에 대하여 "실재하는 모든 것" 또는 "사용할 수 있는 실체"라고 정의하였다. 클래스(Class)는 이러한 객체를 "정의된 클래스 (BluePrint)" 또는 "틀 (flame) "이라고 정의할 수 있다. 즉, 클래스는 객체를 생성하는 데 사용되며 생성된 객체는 클래스 안에서 설계한 그대로 생성된다. 클래스와 객체는 떼려야 뗄 수 없는 관계인 것이다.
여기서 꼭 짚고 넘어가야 할 부분 있다. 클래스는 단지 객체를 생성하는 하나의 틀이라는 것이다. 즉, 클래스는 객체 그 자체가 될 수 없다. 클래스와 객체는 제품의 설계도와 제품으로 비유할 수 있다. 우리의 실생활을 예로 들자면 자동차의 설계도가 자동차 그 자체일 수 없듯 클래스도 객체 그 자체가 될 수 없다는 말이 된다.
위 그림은 자동차의 설계도와 자동차와에 관계를 통하여 클래스와 객체의 차이점을 설명해 주고 있다. 설계도(클래스)가 먼저 생성되고 그 후에 인스턴스를 만들어 주는데 우리는 클래스를 통하여 객체를 생성하는 것을 인스턴스화라고 하며,
이렇게 클래스를 통해 생성된 객체를 인스턴스라고 부른다.
위 그림에서 보듯이 클래스는 객체 자체가 될 수 없고 마치 설계도처럼 인스턴스 (객체)를 생성하기 위한 요건들(구조, 모양 등)을 정의해 놓은 것이 불과하다는 것을 알 수 있다.
그렇다면 왜 클래스를 정의하고 이것을 통하여 객체를 생성해야 할까?
위 붕어빵 가게를 예시로 들어보자. 붕어빵 가게에서 붕어빵을 만들기 위해서는 붕어빵 틀과 조리법 재료들이 필요한데 이 것들 클래스에 제대로 정의해두고 준비해둔다면 붕어빵 가게는 몇 번이고 붕어빵을 찍어낼 수 있을 것이다. 이처럼 우리는 클래스를 한번 잘 생성해두면, 매번 객체를 생성할 때마다. 어떻게 객체를 만들어야 할지 고민할 필요성을 덜어주고 이는 업무의 효율성 및 코드 작성의 편의성을 높여준다.
■클래스의 구성요소와 기본 문법
그렇다면 클래스는 어떻게 정의할 수 있을까?
클래스는 기본적으로 Class 키워드를 사용하여 정의하며, Class를 정의할 때 시작은 대문자로 시작하는 것 이 관례이다.\
class 클래스명 {
//클래스 정의
}
더 나아가 클래스는 4가지의 구성요소로 구성되어 있다. 필드(field) , 메서드(method), 생성자(constructor), 이너 클래스(inner class)가 클래스의 4가지 구성 요소이다.
public class Test {
int x = 10; // (1)필드
void printX() { ... }; // (2)메서드
Test { ... }; //(3) 생성자
class Test2 { ... }; //(4) 이너클래스
}
위 네 가지 클래스를 설명하자면 다음과 같다.
(1) 필드 : 클래스의 속성(Status)을 나타내는 변수이다. 자동차를 예로 색, 자동차 번호, 모델명 등이 있다.
(2) 메서드 : 클래스의 기능(behavior)을 나타내는 함수이다. 자동차를 예로 시동, 정지, 출발 등이 있다
(3) 생성자 : 클래스의 객체를 선언하는 역할이다.
(4) 이너 클래스 : 클래스 내부의 클래스이다.
import java.util.Scanner;
public class SimpleCalculatorTest {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in); //외부 입력을 받을 수 있는 스캐너 객체 생성
System.out.println("첫번째 숫자를 입력해주세요"); //첫번째 숫자 입력
String str1 = scan.nextLine();
System.out.println("연산자를 입력해주세요"); // 연산자 입력
String operator = scan.nextLine();
System.out.println("두번째 숫자를 입력해주세요"); //두번째 숫자 입력.
String str2 = scan.nextLine();
int num1 = Integer.parseInt(str1); //첫번째 숫자를 int 형으로 반환 래퍼클래스 사용
int num2 = Integer.parseInt(str2); //두번째 숫자를 int 형으로 반환 래퍼클래스 사용
int result;
if(operator.equals("+")){ //더하기
result = num1 + num2;
}else if(operator.equals("-")){ //빼기
result = num1 - num2;
}else if(operator.equals("*")){ //곱하기
result = num1 * num2;
}else{
result = num1 / num2; // 나누기
}
System.out.println(num1 + " " + operator + " " + num2 + " = " + result); //결과값 출력
}
}
< 예시 코드 >
■객체 (Object)
앞서 우리는 클래스가 개별 객체(instance)라는 것을 만들기 위한 설계도이며, 클래스를 통해 만들어진 객체가 실제가 있는 실체로서 사용할 수 있다는 것을 배웠다.
앞서 클래스의 설명에서 보았 듯이 객체에는 크게 두 가지의 구성요소 "속성(state)"와 "기능(behavior)"가 있는 것을 알아보았는데 속성과 기능은 각각의 필드와 메서드로 정의된다. 일반적으로 하나의 객체는 다양한 속성과 기능의 집합으로 이루어져 있다. 그리고 이러한 기능들은 이너클래스와 함께 멤버(Member)라는 이름으로 부른다..
위에 멋있는 자동차가 있다. 이 차를 하나의 객체로 생성해보자, 이 차의 객체와 관련된 속성과 기능을 정의한다면 어떤 것이 있을까?
먼저 차가 가지는 일반적인 속성에는 바퀴, 차의 색, 차의 브랜드, 문의 개수 등이 있을 수가 있으며 기능에는 시동걸기, 브레이크, 출발 등이 있을 수가 있다.
이를 클래스를 사용하여 선언하여 보자
class car{
----------- 상태 --------------
private String model; //차 모델
public int wheels; // 바퀴의 개수
public int door; // 문의 개수
public String color; //차의 색
---------- 기능 --------------
void power() {...} //시동걸기
void accelerate() { ... } // 가속
void break() { ... } //브레이크
void zeroHundred() { ... } //제로백
}
코드를 확인해보면, 앞서 언급한 자동차의 속성과 기능들을 가각 필드와 메서드에 선언한 것을 확인할 수 있다. 차와 관련된 데이터들을 클래스라는 울타리 안에서 관리함으로써 데이터의 관리를 용이하게 만들어줄 수 있다. 각 변수들은 각각에 속성에 맞게 알맞은 값으로 정의되었다. 예를 들어, 바퀴는 int를 차의 모델, 색상은 String으로 선언해주었다.
이러한 방식은 우리가 실제 사물을 바라보는 방식에 가까운 방식의 개발 설계 이론이라 할 수 있다.
다음으로 new 키워드를 사용해 객체를 생성하여 클래스에 접근해보자.
class CarState{
public static void main(String[] args) {
CarState jeep = new CarState;
CarState bmw = new CarState;
CarState benz = new CarState;
}
}
■객체 (Object) 의 생성과 활용
■객체 (Object)의 생성
먼저 앞서 간략히 봤듯이 객체는 new 키워드로 생성할 수 있다. 경우에 따라 메서드를 사용해 객체를 생성할 수도 있지만 이 경우도 내부적인 작업을 통해 new 키워드를 통해 객체를 생성하는 것이기 때문에 결국에는 동일한 방식이라 할 수 있다. 객체는 다음과 같이 생성한다.
클래스명 참조_변수명; //인스턴스 참조를 위한 참조변수 선언
클래스명 참조_변수명 = new 생성자(); //인스턴스 생성 후, 객체의 주소를 참조변수에 저장
먼저 특정 클래스 타입의 참조변수를 선언한다. 참조변수가 선언되면, 이제 new 키워드와 생성자를 통해 인스턴스를 생성하여 참조변수에 할당한다. 여기서 참조 변수는 실제 데이터 값이 아니라 실제 데이터가 저장되어 있는 힙 메모리의 주소값을 가리킨다.
new 키워드는 생성된 객체를 힙 메모리에 넣으라는 의미를 가지고 있는데, 생성자(클래스와 동일한 이름을 가졌지만 뒤에 소괄호가 붙음)를 통해 객체가 만들어지면 해당 객체를 힙 메모리에 넣는 역할을 수행하게 된다.
클래스명 참조_변수명 = new 생성자();
먼저 참조 변수는 앞서 설명한대로 실제 데이터 값을 저장하는 것이 아니라 실제 데이터가 위치해있는 힙 메모리의 주소를 저장하는 변수를 의미한다. 따라서 우리가 new 키워드와 생성자를 통해 클래스의 객체를 생성한다는 것은 해당 객체를 힙 메모리에 넣고 그 주소값을 참조변수에 저장하는 것과 같다.
그림에서 볼 수 있는 것처럼 클래스 Person과 참조 변수 p는 각각 클래스 영역과 스택 영역이라는 다른 위치에 저장된다. 한편 생성자로 만들어진 인스턴스는 힙 메모리 영역에 들어가며 객체 내부에는 클래스의 멤버들이 위치하게 된다. 앞서 설명한대로, 참조변수는 객체의 실제 값이 아닌 힙에 저장되어 있는 주소값을 가리키게 된다.
여기서 또 한 가지 주목해야 하는 부분은 메서드의 구현 코드의 위치이다. 보이는 것처럼 메서드 구현 코드는 클래스 영역에 저장되고 객체 안에서는 그 위치를 가리키고 있다. 즉 같은 클래스로 만든 모든 객체는 동일한 메서드 값을 공유하기 때문에 여러 번 같은 메서드를 선언해주는 것이 아니라 한번만 저장해두고 필요한 경우에만 클래스 영역에 정의된 메서드를 찾아 사용할 수 있는 것 이다.
■객체 (Object)의 활용
우리가 기억해야 할 가장 중요한 것은 . 이다. 포인트 연산자라고도 불리는데, 그 의미는 ‘해당 위치에 있는 객체 안을 보세요'라는 뜻을 가지고 있다. 우리는 이 . 을 활용하여 특정 인스턴스 객체의 필드와 메서드, 즉 객체의 멤버들에 접근할 수 있습니다. 기본적인 문법은 다음과 같다.
참조_변수명.필드명 //필드값 불러오기
참조_변수명.메서드명() //메서드 불러오기
import java.util.Scanner;
public class SimpleCalculatorTest {
public static void main(String[] args) {
kunhwi kunhwi = new kunhwi("in Jeju","176cm");
System.out.println("나는" + kunhwi.kunhwi + "에 살고" + kunhwi.stature + "이다");
kunhwi.age();
kunhwi.hobby();
kunhwi.job();
}
}
class kunhwi{
public String kunhwi; //필드 선언
public String stature;
public kunhwi(String kunhwi, String stature){ //인스턴스 초기화를 위한 생성자 함수
this.kunhwi = kunhwi;
this.stature = stature;
}
void age() {
System.out.println("26세");
}
void hobby() {
System.out.println("운동 좋아하는");
}
void job() {
System.out.println("개발자 김건휘입니다..");
}
}
/*
출력값.
나는Jeju에 살고176cm이다
26세
운동 좋아하는
개발자 김건휘입니다..
*/
'Programming > Cs' 카테고리의 다른 글
[OOP] 다형성 (2) | 2022.05.13 |
---|---|
[지식] this vs this() (1) | 2022.05.11 |
[OOP] 객체지향 프로그래밍 (OOP, Object oriented Programming) (2) | 2022.05.10 |
[지식] 변수, 상수, 리터럴, 타입변환 (2) | 2022.05.04 |
[지식] String (0) | 2022.05.04 |