상세 컨텐츠

본문 제목

[JAVA] 자바 스터디 5주차 - 클래스

개발 공부 (etc)/JAVA

by letprogramming 2021. 2. 22. 00:25

본문

반응형
  • 클래스 정의하는 방법
  • 객체 만드는 방법 (new 키워드 이해하기)
  • 메소드 정의하는 방법
  • 생성자 정의하는 방법
  • this 키워드 이해하기

1. 클래스(Class) 정의하는 방법

클래스는 데이터(Data)와 메소드(Method)를 가지는 하나의 자료 구조이다.

클래스를 만드는 방법은 간단하다.

class 라는 키워드를 이용해 클래스를 정의할 수 있다.

 

public class Car{

}

예를 들어, Car 라는 클래스를 정의하고 싶다면

class 키워드 뒤에 클래스명을 작성하면 된다.

맨 앞에 public 이라는 키워드는 접근 지정자로 이 클래스에 접근할 수 있는 범위를 지정해주기 위한 용도이다.


2. 객체(Object) 만드는 방법

객체(Object)란 쉽게 말해서 클래스를 실제로 사용할 수 있도록 만들어내는 것이다.

비유를 하자면 클래스가 틀이라면 객체는 그 틀에 의해 만들어지는 자동차, 쿠키, 옷같은 실제 물건이다.

 

Car bus = new Car();

위에서 선언한 Car라는 클래스의 객체를 생성하기 위해서는 new 키워드를 이용해야 한다.

클래스명 객체명 = new 클래스명();

이러한 방식으로 객체를 생성한다.

 

어떤 클래스로부터 만들어진 객체를 인스턴스(Instance)라고 한다.

객체와 인스턴스의 구분은 실체화가 되었는지(메모리에 할당)를 통해 나눌 수 있다.

 

예를 들어

Car bus;
bus = new Car();

 

 

위의 코드에서 첫 번째 줄에서 bus 는 객체이다.

Car 라는 클래스로부터 실제로 bus라는 것을 구현하기 위해서 만들어낸 객체이다.

 

두 번째 줄의 bus는 인스턴스이다.

실제로 사용하기 위해 메모리를 할당했기 때문이다.

 

첫 번째 줄의 객체 bus는 인스턴스화 시키지 않으면 사용할 수 없다.

즉, 클래스를 사용하기 위해서는 객체를 선언하고 이 객체를 메모리에 할당하는 과정을 거쳐야 사용할 수 있다.

 

메모리 관점에서 위의 코드를 살펴보면

첫 번째 줄에서 bus 라는 변수를 선언하면 스택(Stack) 메모리 영역에 bus 변수를 저장한다.

두 번째 줄에서 new 키워드를 사용해서 인스턴스화를 하면 힙(Heap) 메모리 영역에 객체에 대한 메모리가 할당된다.

그리고 이 bus 변수가 이 할당된 주소를 참조한다.

 

메모리에 대해 이해하기 위해 또 다른 예시를 보면

Car car1 = new Car();
Car car2 = new Car();

car1 = car2;

위의 코드에서

car1 과 car2를 인스턴스화 했다.

car1과 car2는 각각의 메모리 영역을 할당받아 사용할 준비가 된다.

 

 

car1은 메모리를 할당 받아 1234라는 주소를 참조하고 있고,

car2는 5678이라는 주소를 참조하고 있다.

실제로 car1과 car2의 데이터나 메소드를 사용할 일이 있다면

car1과 car2에 저장되어 있는 1234 또는 5678 이라는 주소로 이동하여 작업을 수행할 것이다.

 

마지막 줄의 car1 = car2라는 대입을 수행하면 car1 변수에 car2의 값을 대입하는 것이다.

 

car1 에 저장하는 car2의 값은 바로 car2가 저장하고 있던 5678이라는 주소 값이다.

이제 car1은 car2가 참조하던 5678이라는 메모리 영역을 같이 가리킨다.

 

대입을 한 이후에 car1을 통해 데이터를 수정하면

car2에서 접근했을 때 car1에서 수정한 값을 볼 수 있다.


3. 메소드(Method) 정의하는 방법

메소드란 행동이라고 생각하면 된다.

객체라는 개념 자체가 실제 우리의 현실 세계를 소프트웨어로 담아내기 위해서 나온 개념이다.

달린다, 먹는다, 운전한다, 소리를 지른다 등과 같은 현실 세계에서 일어나는 모든 일을

자바에서는 클래스의 메소드를 통해 구현할 수 있다.

 

이 메소드는 다른 프로그래밍 언어와 같이 함수(Function)로 표현한다.

아까 정의한 Car 라는 클래스 내부에 drive 라는 메소드를 만들어 보자

 

public class Car{
	public void drive(){
    	System.out.println("운전을 시작합니다.");
    }
}

참고로 자바에서 함수는 반드시 클래스 내부에서 선언해야 한다.

클래스 밖에 함수를 정의할 수 없다.

 

위의 코드를 보면

Car 클래스 안에 drive라는 메소드를 선언했다.

 

이 drive 메소드를 수행하면 "운전을 시작합니다." 라는 콘솔 출력을 받을 수 있다.


4. 생성자(Constructor) 정의하는 방법

생성자란 클래스가 인스턴스화될 때 수행되는 메소드이다.

 

비유하자면 변수의 초기화와 유사하다고 할 수 있다.

변수를 선언하고 초기화하는 과정을 통해 변수에 초기 값을 대입하듯이,

객체를 선언하고 인스턴스화 하는 과정에서 객체의 데이터들을 초기화하거나

특정한 행동을 하도록 지정할 수 있다.

 

만약 생성자로 데이터 값들을 초기화하지 않은 상태에서

객체의 데이터를 수정하거나 사용할 경우 오류가 발생할 수 있기 때문에

생성자는 필수로 구현하는 것이 좋다.

 

생성자를 정의하는 방법에는 규칙이 존재한다.

먼저 클래스의 이름과 생성자의 이름은 같아야 한다.

위의 Car 라는 클랫의 생성자는 Car() 라는 이름을 가진 메소드이어야 한다.

 

또한 생성자는 값을 리턴하지 않는다.

일반적인 메소드는 return을 통해 값을 return 할 수 있고 void라는 형식의 메소드는 값을 return 하지 않는다.

생성자는 무조건 값을 반환하지 않는다. 그렇기 때문에 void 라는 키워드도 적지 않는다.

 

Car 클래스의 생성자를 정의해보자

public class Car{
	private int gas;
	private int age;
    
	public Car(){
    	gas = 100;
        age = 0;
	}
    
	public void drive(){
    	System.out.println("운전을 시작합니다.");
    }
}

위처럼 Car 클래스를 정의하고

Car newCar = new Car();

newCar라는 객체를 인스턴스화하면

정의한 Car() 생성자가 실행되면서 newCar 객체가 가지고 있는 gas와 age의 값들이 각각 100과 0으로 초기화된다.

 

생성자는 자바의 오버로딩(Overloading)을 통해 여러 개를 정의할 수 있다.

오버로딩이란 같은 이름의 메소드를 파라미터의 개수에 따라 여러 개로 정의할 수 있는 것이다.

 

위 Car 클래스에서 gas와 age를 정해진 100과 0이 아닌 받은 값으로 정해주는 생성자를 새롭게 추가해보자

 

public class Car{
	private int gas;
	private int age;
    
	public Car(){
		gas = 100;
		age = 0;
	}
    
	public Car(int gas, int age){
		this.gas = gas;
		this.age = age;
	}
    
	public void drive(){
		System.out.println("운전을 시작합니다.");
    }
}

this 키워드는 뒤에서 알아보도록 하고 새로운 생성자부터 살펴보자

 

같은 이름의 Car() 메소드를 두 개 정의한 것을 확인할 수 있다.

Car oldCar = new Car(80, 5);

위와 같이 oldCar를 인스턴스화하면서 Car() 메소드에 파라미터를 넣어주면 새롭게 만든 생성자가 수행된다.

이 처럼 오버로딩은 파라미터에 따라서 같은 이름의 메소드도 구분하여 수행할 수 있도록 해준다.

 

만약 파라미터에 80과 5를 넘겨주지 않고 아까처럼 빈 괄호 () 만 작성한다면

이전에 정의했던 gas = 100 과 age = 0으로 초기화되는 생성자가 수행될 것이다.

 

파라미터가 없는 생성자를 기본 생성자라고 하며

파라미터가 있는 생성자를 파라미터 생성자라고 부른다.


5.  this 키워드 이해하기

생성자를 공부하면서 파라미터 생성자에서 this 키워드를 사용했다.

 

이 this 키워드는 말 그대로 "자기 자신"을 의미한다.

여기서 자기 자신은 현재 이 코드가 실행되고 있는 클래스를 의미한다.

 

위 Car 클래스의 생성자를 예시로 살펴보면

public class Car{
	private int gas;
	private int age;
    
	public Car(){
		gas = 100;
		age = 0;
	}
    
	public Car(int gas, int age){
		this.gas = gas;
		this.age = age;
	}
    
	public void drive(){
		System.out.println("운전을 시작합니다.");
    }
}

두 번째 생성자에서 gas와 age라는 int형의 매개변수를 받아 Car 클래스가 가지고 있는 gas와 age라는 멤버 변수에 할당했다.

그러나 gas와 age라는 이름을 Car 클래스에서도 가지고 있고 Car() 생성자에서도 사용한다.

우리가 지금 하고 싶은 것은 받은 gas를 Car 객체가 가지고 있는 gas에 대입하고 싶고 age도 마찬가지이다.

 

하지만 만약에

public Car(int gas, int age){
	gas = gas;
	age = age;
}

this 키워드 없이 위처럼 코드를 작성하면

이 gas가 클래스의 멤버 변수인 gas인 것을 구분할 수가 없다.

이렇게 클래스의 멤버 변수와 일반 지역 변수들을 구분하기 위한 키워드가 this이다.

 

this 키워드를 사용하면 변수뿐만 아니라 현재 클래스가 가지고 있는 메소드들도 호출할 수 있다.

예를 들어 Car 클래스에서 정의한 drive 메소드를 클래스 내부에서 수행할 일이 있다면

this.drive();

위 처럼 클래스 내부에서 사용자 정의 메소드를 호출할 수 있다.

반응형

관련글 더보기