생성자와 메소드란?

nkcho·2023년 2월 21일

개념 아카이빙

목록 보기
6/9

클래스의 구성 요소는 아래 세 가지로 이루어져 있다.

  • 필드 (클래스 변수)
  • 생성자
  • 메소드 (클래스 메소드)

이번 글에서는 생성자와 메소드에 대해 깊이 알아보자.

생성자란?

  • 일반 명사적 의미?
    • 생성 : 사물이 생겨남. 또는 사물이 생겨 이루어지게함
  • 고유 명사적 의미?
    • 객체 지향 프로그래밍에서 객체의 초기화를 담당하는 서브루틴(일정 코드 부분)을 가리킨다.
    • 생성자는 객체가 처음 생성될 때 호출되어 멤버 변수를 초기화하고 필요에 따라 자원을 할당하기도 한다. 객체의 생성 시에 호출되기 때문에 ‘생성자'라는 이름이 붙었다.
    • 생성자는 대체로 함수와 같은 모양을 하고 있지만 값을 반환하지 않는다는 점에서 엄밀한 의미의 함수는 아니다.
    • 자바에서 생성자는 클래스의 이름과 같은 이름을 가진다. 또한 함수 인자의 개수와 타입에 따라 여러개의 서로 다른 생성자를 정의할 수 있다.
  • 생성자는 왜 쓰는가?
    • 객체를 초기화 해야 하기 때문. 객체의 초기화가 필요한 이유는? 클래스가 객체를 생성/호출 하였을 때, 객체의 필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 해야 하기 때문.
    • 클래스에서 생성자가 없으면 객체에 접근 자체를 하지 못함. (따라서 기본 생성자라는 개념이 있는 것이고, 클래스 내부에 어떤 생성자도 없을 시 객체 생성 과정에서 컴파일러가 자동으로 추가하는 것)
    • 메모리 구조상 new 연산자가 생성자를 정상적으로 실행시키면 힙 영역에 객체가 생성되고, 생성된 객체의 주소가 클래스 타입 변수에 리턴되어 객체에 접근할 수 있게 되는데 생성자가 실행되지 않으면 힙 영역에 객체가 생성되지 않으니 객체의 주소도 리턴받을 수 없다.
  • 생성자는 어떻게 사용하는가?
    • 메소드명이 클래스명과 동일하고 리턴 자료형을 정의하지 않는다. (void도 사용하지 않는다)
    • 생성자는 객체가 생성될 때 호출된다. 즉, new 키워드가 사용될 때 호출된다.
    • 만약 클래스에 생성자가 하나도 없다면 컴파일러는 자동으로 디폴트 생성자를 추가한다. 하지만 사용자가 작성한 생성자가 하나라도 구현되어 있다면 컴파일러는 디폴트 생성자를 추가하지 않는다.
class Animal {
    String name;

    void setName(String name) {
        this.name = name;
    }
}

class Dog extends Animal {
    void sleep() {
        System.out.println(this.name + " zzz");
    }
}

class HouseDog extends Dog {
    HouseDog(String name) {
        this.setName(name);
    } // 생성자 생성

    void sleep() {
        System.out.println(this.name + " zzz in house");
    }

    void sleep(int hour) {
        System.out.println(this.name + " zzz in house for " + hour + " hours");
    }
}

public class Sample {
    public static void main(String[] args) {
        HouseDog dog = new HouseDog("happy");
				// 만약 HouseDog dog = new HouseDog();라고 쓰게 되면 컴파일 오류가 발생. 
				// 생성자를 사용하면 setName("happy")와 같은 필수적인 행동을 객체 생성시 제어할 수 있다. 
        System.out.println(dog.name);
    }
}
  • 메소드에 오버로딩이 있는 것과 마찬가지로 생성자에도 오버로딩이 있다. 즉, 아래처럼 여러개의 생성자를 만들 수 있다.
class Animal {
    String name;

    void setName(String name) {
        this.name = name;
    }
}

class Dog extends Animal {
    void sleep() {
        System.out.println(this.name + " zzz");
    }
}

class HouseDog extends Dog {
    HouseDog(String name) {
        this.setName(name);
    }

    HouseDog(int type) {
        if (type == 1) {
            this.setName("yorkshire");
        } else if (type == 2) {
            this.setName("bulldog");
        }
    }

    void sleep() {
        System.out.println(this.name + " zzz in house");
    }

    void sleep(int hour) {
        System.out.println(this.name + " zzz in house for " + hour + " hours");
    }
}

public class Sample {
    public static void main(String[] args) {
        HouseDog happy = new HouseDog("happy");
        HouseDog yorkshire = new HouseDog(1);
        System.out.println(happy.name);  // happy 출력
        System.out.println(yorkshire.name);  // yorkshire 출력
    }
}
  • 생성자의 예시

    • 기본 생성자(디폴트 생성자) : 정의할 게 없는 생성자

      class Calculator {
      
      	**//생성자 정의 - 기본 생성자(디폴트 생성자)
      	public Calculator(){
      
      	}**
      	
      	public static void main(String[] args){
      		System.out.println("Calculator start");
      
      		Calculator calc = new Calculator();
      
      		int a = 10;
      		int b = 15;
      
      		System.out.println(a + " + " + b + " = " + calc.add(a, b));
      		System.out.println(a + " - " + b + " = " + calc.subtract(a, b));
      		System.out.println(a + " * " + b + " = " + calc.multiply(a, b));
      		System.out.println(a + " / " + b + " = " + calc.divide(a, b));
      	}
      
          // 메소드 정의
      	public int add(int x, int y){
      		return x + y;
      	}
      
      	public int subtract(int x, int y){
      		return x - y;
      	}
      
      	public int multiply(int x, int y){
      		return x * y;
      	}
      
      	public int divide(int x, int y){
      		return x / y;
      	}
      
      }
    • 매개변수가 있는 생성자 = 명시적 생성자 / 매개변수가 없는 생성자 = 묵시적 생성자

      class Calculator2 {
      		int int1, int2;
      
      // 매개변수를 받는 생성자 생성
      		public Calculator2(int num1, int num2){
      			int1 = num1;
      			int2 = num2;
      		}
      
      		public static void main(String[] args){
      			System.out.println("Calculator start");
      
      			int a = 10;
      			int b = 15;
      
      		// 객체정의
      		Calculator2 calc = new Calculator2(a, b);
      
      		System.out.println(a + " + " + b + " = " + calc.add());
      		System.out.println(a + " - " + b + " = " + calc.subtract());
      		System.out.println(a + " * " + b + " = " + calc.multiply());
      		System.out.println(a + " / " + b + " = " + calc.divide());
      		}
      
      public int add(){
          return int1 + int2;
      }
      
      public int subtract(){
          return int1 - int2;
      }
      
      public int multiply(){
          return int1 * int2;
      }
      
      public int divide(){
          return int1 / int2;
      }

메소드란?

  • 일반 명사적인 의미? 방법
  • 고유 명사적인 의미? 어떠한 특정 작업을 수행하기 위한 명령문의 집합
  • 클래스 안에서 선언하는, 입력값을 받아 특정 행동을 수행하고 결과를 호출자에게 리턴하는 명령문 콜렉션.
  • 객체 지향 프로그래밍(OOP)의 메서드는 메시지 및 객체와 관련된 절차다. 객체는 데이터와 동작으로 구성된다. 이들은 다양한 소비자가 객체를 어떻게 활용할 수 있는지를 지정하는 인터페이스로 구성된다. 데이터는 객체의 속성으로 표시되고 동작은 메서드로 표시된다.
  • 예를 들어 Window 객체는 open, close와 같은 메서드를 가질 수 있으며 상태(특정 시점에서 열려 있거나 닫혀 있는지 여부)는 속성이 된다. 클래스 기반 프로그래밍에서 메서드는 클래스에 정의되고 객체는 주어진 클래스의 인스턴스다.

메소드를 왜 사용하는가?

  • 중복되는 코드의 반복적인 프로그래밍을 피할 수 있고, 모듈화(캡슐화)로 인해 코드의 가독성도 좋아짐
    • 메서드가 제공하는 가장 중요한 기능 중 하나는 메서드 재정의다. 같은 이름을 여러 종류의 클래스에 사용할 수 있다. 이를 통해 보내는 객체가 메서드를 호출하고 해당 동작의 구현을 수신 객체에 위임할 수 있다.
    • 자바 프로그래밍의 메서드는 클래스 객체의 동작을 설정한다. 또한 메서드는 다른 클래스가 객체의 속성에 접근하고 수정하는 데 사용하는 인터페이스를 제공한다. 이걸 캡슐화라고 한다.
  • 프로그램에 문제가 발생하거나 기능의 변경이 필요할 때도 손쉽게 유지보수를 할 수 있게 된다.
  • 메소드를 작성할 때는 되도록 하나의 메소드가 하나의 기능만을 수행하도록 작성하는 것이 좋다.

메소드는 어떻게 사용하는가?

접근제어자 반환타입 메소드이름(매개변수목록) { // 선언부

    // 구현부

}
  1. 접근 제어자 : 해당 메소드에 접근할 수 있는 범위를 명시한다.
    1. public
    2. default
    3. protected
    4. private
  2. 반환 타입(return type) : 메소드가 모든 작업을 마치고 반환하는 데이터의 타입을 명시한다.
    1. 정수 타입이라면 int
    2. 문자열이라면 String
    3. 만약 아무것도 반환하지 않는다면 void 라고 쓴다.
  3. 메소드 이름 : 메소드를 호출하기 위한 이름을 명시한다.
  4. 매개변수 목록(parameters) : 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시한다.
  5. 구현부 : 메소드의 고유 기능을 수행하는 명령문의 집합.
  6. 메소드 시그니처(method signature) : 메소드의 선언부에 명시되는 매개변수의 리스트를 가리킨다. 만약 두 메소드가 매개변수의 개수와 타입, 그 순서까지 모두 같다면, 이 두 메소드의 시그니처는 같다고 할 수 있다.
//메소드 예시
class Car {

		//변수
		private int currentSpeed;

    private int accelerationTime;

    ...

		//메소드
		public void accelerate(int speed, int second) { // 선언부

        // 구현부

        System.out.println(second + "초간 속도를 시속 " + speed + "(으)로 가속함!!");

    }

    ...

}

profile
FE developer

0개의 댓글