Java (자바)

[Java] 클래스 - (2) 클래스, 생성자와 메서드

Oscar:) 2022. 7. 6. 19:15

 

지난 포스팅에서는 클래스에 대해 공부하기 전,

'객체 지향적 프로그래밍' 에 대해 알아보았다.

 

이번 포스팅에서는 클래스에 대해 알아보자.

 

 


 

클래스란 ?

 

앞선 포스팅에서 다뤘던 '객체 지향적 프로그래밍' 의 중심인

'객체' 를 정의하는 틀이라고 할 수 있다.

 

객체를 만들어 내기 위한 설계도와 같은 개념으로 설명하기도 한다.

 

또한,

우리가 만들어내는 어떠한 프로그램의 구성 요소 중 일부라고 볼 수도 있겠다.

 

 

이제 클래스의 구성 요소, 생성자와 메서드에 대해 알아보자.

 

생성자란? (constructor)

 

객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화할 수 있는 메서드의 일종이다.

new 키워드를 사용하여 객체를 생성할 때, 자동으로 호출된다.

 

 

메서드의 일종으로 분류하였다지만, 일반적으로 사용하는 메서드와는 엄연히 다르다.

 

· 생성자와 메서드의 차이점

 

생성자의 이름은 반드시 해당 클래스의 이름과 같아야 한다.

코드상으로 생성자 앞에는 접근 제한자만 사용할 수 있다.

반환값이 없으며, 그렇다고 void를 선언하지도 않는다. 등

 

 

· 생성자의 특징

 

모든 클래스에는 최소한 1개 이상의 생성자가 정의되어 있어야 한다.

하지만, 생성자를 따로 정의해주지 않고도 인스턴스를 생성할 수 있다.

 

자바 컴파일러가 기본적으로 기본 생성자(default constructor) 를 제공해주기 때문이다.

 

 

* 기본 생성자(default constructor) :

매개변수를 가지지 않으며, 어떠한 코드도 존재하지 않는다.

 

매개변수를 가지는 생성자를 하나라도 정의했다면,

기본 생성자는 자동으로 추가되지 않는다.

 

물론 기본 생성자를 따로 정의해준다면,

두개 이상의 생성자를 사용할 수도 있다.

 

 

메서드란? (method)

 

특정 작업을 수행하기 위한 명령문의 집합이라고 정의한다.

 

주로 '동사'의 느낌을 표현하는 모든 작업을 메서드로 사용한다고 생각하면 쉽다.

 

 

· 메서드의 특징

 

문법상으로, 반드시 반환 타입(return type) 을 명시해줘야 한다.

반환 값을 명시하지 않으려면 void를 작성해준다.

 

 

메서드를 잘 사용한다면, 중복되는 코드의 반복적인 작업을 지양할 수 있다.

 

메서드화를 진행하다 보면, 자연스레 모듈화가 진행된다.

(모듈화의 장점은 객체 지향적 프로그래밍의 장점과 동일한 맥락이다.)

 


클래스를 처음 공부한다면,

이론적으로만 이해하기에는 버거울 것이다.

(필자 본인도 그랬다.)

 

그렇기에 직접 코드를 작성하여 2개의 클래스를 만들고,

생성자와 메서드를 이용하여 데이터를 전달하는 예제를 통해 공부해보자.

 

클래스 사용 예제

 

● 먼저 두개의 클래스를 생성해준다.

(Class1.java / Class2.java)

 

 

Class1 클래스에는 main 메서드를 함께 생성해준다.

(main 메서드에서 코드가 실행된다.)

 

Class1.java

public class Class1 { // Class1 클래스
	
	public static void main(String[] args) { // main 메서드
    
	}

}

 

 

Class2 클래스는 Class1 클래스로 넘겨줄 정보들을 작성해줄 것이다.

(생성자, 메서드, 변수 등)

 

Class2.java

public class Class2 { // Class2 클래스
	
    // 변수 생성
	String name;
	int age;

}

예시로, 사용자의 이름와 나이를 담을 변수를 생성해주었다.

 


 

 

● 생성자의 매개변수에 값을 담아서 작성해보겠다.

 

Class1.java

public class Class1 {
	
	public static void main(String[] args) {
		
         // new 연산자를 사용하여 Class2 생성자를 호출하여 oscar 객체에 담는다.
		Class2 oscar = new Class2("오스카",27);
       
       // Class2 클래스에 있는 speak() 메서드를 호출한다.
		oscar.speak();
		
	}

}

 

Class2.java

public class Class2 {
	
	String name;
	int age;
	
    // 매개변수가 있는 생성자
	public Class2(String name, int age) {
		this.name = name;
		this.age = age;
	}
    
	// 반환타입이 없는(void), 매개변수가 없는 메서드
	public void speak() {
		System.out.println( name + "는 " + age + "세 입니다");
	}

}

 

Class2 클래스의 생성자를 보면,

매개변수로 String name, int age 를 작성하였다.

 

따라서 Class1 에서 Class2 를 호출할 때,

매개변수의 위치에 알맞게 값을 대입해주어야 한다.

(name, age 순서이기 때문에, "오스카", 27 로 입력하였다.)

 

 

출력 결과는 다음과 같다.

 


 

● 메서드의 매개변수에 값을 담아서 작성해보겠다.

 

Class1.java

public class Class1 {
	
	public static void main(String[] args) {
		
        // Class2 클래스의 기본 생성자 호출
		Class2 jayden = new Class2(); 
		
        // Class2 클래스에 있는 tell(String name, int age) 메서드 호출
		jayden.tell("제이든",36);
		
	}

}

 

Class2.java

public class Class2 {
	
//	String name;
//	int age;
	
    // 매개변수가 없는 생성자 (기본 생성자)
	public Class2() { 
    
	};
	
    // 매개변수가 있는 메서드
	public void tell(String name,int age) {
		System.out.println(name + "은 " + age + "세 입니다");
	}

}

 

Class2 클래스에서 작성한 생성자의 경우,
위에서 설명한 기본 생성자(default constructor)에 해당한다.
(즉, 굳이 작성해주지 않아도 컴파일러가 자동 제공해준다.)

 

Class2 클래스의 tell() 메서드를 보면,

매개변수로 String name, int age 를 작성하였다.

 

따라서 Class1 클래스에서 tell() 메서드를 호출할 때,

매개변수에 값을 대입해주었다.

 

 

출력 결과는 다음과 같다.

 


 

● 두가지 방식을 모두 작성해버린(?) 코드이다.

 

Class1.java

public class Class1 {
	
	public static void main(String[] args) {
		
        // 생성자 매개변수에 데이터 입력
		Class2 oscar = new Class2("오스카",27); 

		oscar.speak();
		
		Class2 jayden = new Class2();
		
        // 메서드 매개변수에 데이터 입력
		jayden.tell("제이든",36); 
		
	}

}

 

Class2.java

public class Class2 {
	
	String name;
	int age;
	
    // 매개변수가 없는 생성자
	public Class2() { 
		
	};
	
    // 매개변수가 있는 생성자
	public Class2(String name, int age) { 
		this.name = name;
		this.age = age;
	}
	
    // 매개변수가 있는 메서드
	public void tell(String name,int age) { 
		System.out.println(name + "은 " + age + "세 입니다");
	}
    
    // 매개변수가 없는 메서드
	public void speak() { 
		System.out.println( name + "는 " + age + "세 입니다" );
	}

}

 

보다시피, 생성자를 여러개 생성하여 사용하는 것이 가능하다.

(생성자 오버로딩)

 

메서드는, 매개변수 사용 유무에 대한 가독성을 높이기 위해서

메서드의 이름을 tell / speak 로 구분지어 사용했다.

(사실, 메서드 또한 오버로딩을 통해서 메서드명을 똑같이 사용할 수도 있다.

오버로딩은 추후에 따로 포스팅하겠다.)

 

 

출력 결과는 다음과 같다.

 


 

● 번외, 데이터 전달에 실패한 케이스

 

생성자, 메서드의 매개변수를 알맞게 사용해야 한다.

그렇지 않다면 다음과 같이 default 값을 마주하게 될 것이다.

 

출력 결과

String 의 default 값인 'null'

int 의 default 값인 '0' 이 출력된다.

 

 


 

생성자와 메서드를 사용하여 여러 클래스를 사용하는 방법에 대해 알아보았다.

 

이제 main 메서드를 그만 괴롭히고,

효율적으로 클래스를 분류해보자.

 

객체 지향적 프로그래밍을 시작하는 것이다..!

 


 

to. 클래스를 처음 공부하는 분들에게

 

어떠한 프로그램을 만드려고 할 때,

클래스를 분류하는 것에 확신이 없어서, 겁이 날 수도 있다.

 

 

클래스를 분류하는 기준은 본인이 정하면 된다.

 

필자 또한, 처음으로 클래스에 대해 공부했을 때,

'감히 나 까짓게 무슨 모듈화야..'

라는 생각을 했던 적이 있었다.

 

하지만 클래스를 분류하는 것을 시작으로

그 프로그램의 틀이 잡히게 되며,

메서드도 다양하게 분류하며 프로그램을 세분화할 수 있게 된다.

 

 

클래스는 많이 사용해 볼수록, 더 많이 알아가게 되는 것 같다.

'내 프로그램' 이라는 자신감을 갖고 여러 클래스를 사용해보자 !