메소드와 생성자

    1) 메소드의 개념

     

    메소드(method)

     

    메소드(method)란 어떠한 특정 작업을 수행하기 위한 명령문의 집합

     

    메소드의 사용 목적

     

    클래스에서 메소드를 작성하여 사용하는 이유는 중복되는 코드의 반복적인 프로그래밍을 피할 수 있기 때문

    모듈화로 인해 코드의 가독성도 좋아짐

    프로그램에 문제가 발생하거나 기능의 변경이 필요할 때도 손쉽게 유지보수를 할 수 있음

     

    메소드 정의

     

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

    1. 접근 제어자 : 해당 메소드에 접근할 수 있는 범위를 명시

    2. 반환 타(return type) : 메소드가 모든 작업을 마치고 반환하는 데이터의 타입을 명시

    3. 메소드 이름 : 메소드를 호출하기 위한 이름을 명시

    4. 매개변수 목록(parameters) : 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시

    5. 구현부 : 메소드의 고유 기능을 수행하는 명령문의 집합

     

    // Car 클래스의 accelerate() 메소드를 정의하는 예제
    
    class Car {
    
        private int currentSpeed;
    
        private int accelerationTime;
    
        ...
    
    ①  public void accelerate(int speed, int second) { // 선언부
    
            // 구현부
    
            System.out.println(second + "초간 속도를 시속 " + speed + "(으)로 가속함!!");
    
        }
    
        ...
    
    }

     

    메소드 호출

     

    1. 객체참조변수이름.메소드이름();                  // 매개변수가 없는 메소드의 호출
    
    2. 객체참조변수이름.메소드이름(인수1, 인수2, ...); // 매개변수가 있는 메소드의 호출
    
    
    // 앞서 정의한 accelerate() 메소드를 호출하는 예제
    
    Car myCar = new Car();   // 객체를 생성함.
    
    myCar.accelerate(60, 3); // myCar 인스턴스의 accelerate() 메소드를 호출함.
    
    
    // 실제로 accelerate() 메소드를 정의하고 호출하는 예제
    
    class Car {
    
        private int currentSpeed;
    
        private int accelerationTime;
    
     
    
        public void accelerate(int speed, int second) {
    
            System.out.println(second + "초간 속도를 시속 " + speed + "(으)로 가속함!!");
    
        }
    
    }
    
     
    
    public class Method01 {
    
        public static void main(String[] args) {
    
            Car myCar = new Car();   // 객체 생성
    
            myCar.accelerate(60, 3); // 메소드 호출
    
        }
    
    }

     

     

    2) 생성자

     

    인스턴스 변수의 초기화

     

    자바에서 클래스 변수와 인스턴스 변수는 별도로 초기화하지 않으면, 다음 값으로 자동 초기화

     

    생성자(constructor)

     

    자바에서는 객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화할 수 있는 생성자라는 메소드를 제공

    1. 생성자는 반환값이 없지만, 반환 타입을 void형으로 선언하지 않음

    2. 생성자는 초기화를 위한 데이터를 인수로 전달받을 수 있음

    3. 객체를 초기화하는 방법이 여러 개 존재할 경우에는 하나의 클래스가 여러 개의 생성자를 가질 수 있음

        즉, 생성자도 하나의 메소드이므로, 메소드 오버로딩이 가능

     

    // Car 클래스를 선언하면서 여러 개의 생성자를 선언하는 예제
    
    Car(String modelName) {}
    
    Car(String modelName, int modelYear) {}
    
    Car(String modelName, int modelYear, String color) {}
    
    Car(String modelName, int modelYear, String color, int maxSpeeds) {}

     

    생성자의 선언

     

    1. 클래스이름() { ... }                  // 매개변수가 없는 생성자 선언
    
    2. 클래스이름(인수1, 인수2, ...) { ... } // 매개변수가 있는 생성자 선언
    // Car 클래스의 생성자를 선언하는 예제
    
    Car(String modelName, int modelYear, String color, int maxSpeeds) {
    
        this.modelName = modelName;
    
        this.modelYear = modelYear;
    
        this.color = color;
    
        this.maxSpeed = maxSpeed;
    
        this.currentSpeed = 0;
    
    }

     

    생성자의 호출

     

    // new 키워드를 사용하여 객체를 생성할 때 자동으로 생성자가 호출
    
    class Car {
    
        private String modelName;
    
        private int modelYear;
    
        private String color;
    
        private int maxSpeed;
    
        private int currentSpeed;
    
     
    
        Car(String modelName, int modelYear, String color, int maxSpeed) {
    
            this.modelName = modelName;
    
            this.modelYear = modelYear;
    
            this.color = color;
    
            this.maxSpeed = maxSpeed;
    
            this.currentSpeed = 0;
    
        }
    
     
    
        public String getModel() {
    
            return this.modelYear + "년식 " + this.modelName + " " + this.color;
    
        }
    
    }
    
     
    
    public class Method02 {
    
        public static void main(String[] args) {
    
            Car myCar = new Car("아반떼", 2016, "흰색", 200); // 생성자의 호출
    
            System.out.println(myCar.getModel()); // 생성자에 의해 초기화되었는지를 확인함.
    
        }
    
    }

     

    기본 생성자(default constructor)

     

    자바의 모든 클래스에는 하나 이상의 생성자가 정의되어 있어야 함

    하지만 특별히 생성자를 정의하지 않고도 인스턴스를 생성할 수 있음

    이것은 자바 컴파일러가 기본 생성자라는 것을 기본적으로 제공해 주기 때문

    기본 생성자는 매개변수를 하나도 가지지 않으며, 아무런 명령어도 포함하고 있지 않음.

     

    클래스이름() {}
    // 기본 생성자의 예제
    
    Car() {}
    // Car 클래스에 생성자를 정의하지 않고, 기본 생성자를 호출하는 예제
    
    class Car {
    
        private String modelName = "소나타";
    
        private int modelYear = 2016;
    
        private String color = "파란색";
    
     
    
        public String getModel() {
    
            return this.modelYear + "년식 " + this.color + " " + this.modelName;
    
        }
    
    }
    
     
    
    public class Method03 {
    
        public static void main(String[] args) {
    
            Car myCar = new Car();                // 기본 생성자의 호출
    
            System.out.println(myCar.getModel()); // 2016년식 파란색 소나타
    
        }
    
    }

    // 매개변수를 가지는 생성자를 하나라도 정의했다면, 기본 생성자는 자동으로 추가되지 않음
    
    class Car {
    
        private String modelName;
    
        private int modelYear;
    
        private String color;
    
        private int maxSpeed;
    
        private int currentSpeed;
    
     
    
    ①  Car(String modelName, int modelYear, String color, int maxSpeed) {
    
            this.modelName = modelName;
    
            this.modelYear = modelYear;
    
            this.color = color;
    
            this.maxSpeed = maxSpeed;
    
            this.currentSpeed = 0;
    
        }
    
     
    
        public String getModel() {
    
            return this.modelYear + "년식 " + this.modelName + " " + this.color;
    
        }
    
    }
    
     
    
    public class Method04 {
    
        public static void main(String[] args) {
    
    ②      Car myCar = new Car(); // 기본 생성자의 호출
    
    ③      // Car myCar = new Car("아반떼", 2016, "흰색", 200); // 생성자의 호출
    
     
    
            System.out.println(myCar.getModel()); // 생성자에 의해 초기화되었는지를 확인함.
    
        }
    
    }

     

     

    3) this와 this()

     

    this 참조 변수

     

    this 참조 변수는 인스턴스가 바로 자기 자신을 참조하는 데 사용하는 변수

    // Car 클래스의 생성자를 나타낸 예제
    
    class Car {
    
        private String modelName;
    
        private int modelYear;
    
        private String color;
    
        private int maxSpeed;
    
        private int currentSpeed;
    
     
    
        Car(String modelName, int modelYear, String color, int maxSpeed) {
    
            this.modelName = modelName;
    
            this.modelYear = modelYear;
    
            this.color = color;
    
            this.maxSpeed = maxSpeed;
    
            this.currentSpeed = 0;
    
        }
    
        ...
    
    }

    위의 예제처럼 생성자의 매개변수 이름과 인스턴스 변수의 이름이 같은 경우에는 인스턴스 변수 앞에 this 키워드를

    붙여 구분해야 함

     

    this() 메소드

     

    this() 메소드는 생성자 내부에서만 사용할 수 있음

    같은 클래스의 다른 생성자를 호출할 때 사용

    this() 메소드에 인수를 전달하면, 생성자 중에서 메소드 시그니처(메소드의 이름과 메소드의 원형에 명시되는 매개변수 리스트)가 일치하는 다른 생성자를 찾아 호출해 줌

    // this 참조 변수와 this() 메소드를 사용한 예제
    
    class Car {
    
        private String modelName;
    
        private int modelYear;
    
        private String color;
    
        private int maxSpeed;
    
        private int currentSpeed;
    
     
    
        Car(String modelName, int modelYear, String color, int maxSpeed) {
    
            this.modelName = modelName;
    
            this.modelYear = modelYear;
    
            this.color = color;
    
            this.maxSpeed = maxSpeed;
    
            this.currentSpeed = 0;
    
        }
    
     
    
        Car() {
    
            this("소나타", 2012, "검정색", 160); // 다른 생성자를 호출함.
    
        }
    
     
    
        public String getModel() {
    
            return this.modelYear + "년식 " + this.modelName + " " + this.color;
    
        }
    
    }
    
     
    
    public class Method05 {
    
        public static void main(String[] args) {
    
            Car tcpCar = new Car(); System.out.println(tcpCar.getModel());
    
        }
    
    }

     

     

    4) 메소드 오버로딩

     

    메소드 시그니처(method signature)

     

    메소드 시그니처란 메소드의 선언부에 명시되는 매개변수의 리스트

    만약 두 메소드가 매개변수의 개수 타입, 순서까지 모두 같다면, 이 두 메소드의 메소드 시그니처는 같음

     

    메소드 오버로딩(method overloading)

     

    메소드 오버로딩이란 같은 이름의 메소드를 중복하여 정의하는 것

    매개변수의 개수나 타입을 다르게 하면, 하나의 이름으로 메소드를 작성할 수 있음

    즉, 메소드 오버로딩은 서로 다른 시그니처를 갖는 여러 메소드를 같은 이름으로 정의하는 것

    메소드 오버로딩을 사용함으로써 메소드에 사용되는 이름을 절약할 수 있음

    메소드를 호출할 때 전달해야 할 매개변수의 타입이나 개수에 대해 크게 신경을 쓰지 않고 호출할 수 있게 됨

    메소드 오버로딩은 객체 지향 프로그래밍의 특징 중 하나인 다형성(polymorphism)을 구현하는 방법 중 하나

    // 메소드 오버로딩의 대표적인 예 println() 메소드
    
    1. println()
    
    2. println(boolean x)
    
    3. println(char x)
    
    4. println(char[] x)
    
    5. println(double x)
    
    6. println(float x)
    
    7. println(int x)
    
    8. println(long x)
    
    9. println(Object x)
    
    10. println(String x)

     

    메소드 오버로딩의 조건

     

    1. 메소드의 이름이 같아야 함

    2. 메소드의 시그니처, 즉 매개변수의 개수 또는 타입이 달라야 함

     

    메소드 오버로딩의 예제

     

    // 메소드의 원형 예제
    
    1. void display(int num1)              // 전달받은 num1을 그대로 출력함.
    
    2. void display(int num1, int num2)    // 전달받은 두 정수의 곱을 출력함.
    
    3. void display(int num1, double num2) // 전달받은 정수와 실수의 합을 출력함.
    
    
    // 함수의 호출 예제
    
    1. display(10);       // 1번 display() 메소드 호출 -> 10
    
    2. display(10, 20);   // 2번 display() 메소드 호출 -> 200
    
    3. display(10, 3.14); // 3번 display() 메소드 호출 -> 13.14
    
    4. display(10, 'a');  // 2번과 3번 모두 호출 가능
    
    
    // display() 메소드를 다양한 시그니처로 오버로딩하는 예제
    
    class Test {
    
        static void display(int num1) { System.out.println(num1); }
    
    ①  static void display(int num1, int num2) { System.out.println(num1 * num2); }
    
    
     
        static void display(int num1, double num2) { System.out.println(num1 + num2); }
    
    }
    
     
    
    public class Method06 {
    
        public static void main(String[] args) {
    
            Test myfunc = new Test();
    
     
    
            myfunc.display(10);
    
            myfunc.display(10, 20);
    
            myfunc.display(10, 3.14);
    
    ②      myfunc.display(10, 'a');
    
        }
    
    }

     

     

    5) 재귀 호출

     

    재귀 호출(recursive call)

     

    재귀 호출이란 메소드 내부에서 해당 메소드가 또다시 호출되는 것

    재귀 호출은 자기가 자신을 계속해서 호출하므로 끝없이 반복됨

    따라서 메소드 내에 재귀 호출을 중단하도록 조건이 변경될 명령문을 반드시 포함해야 함

     

    재귀 호출의 개념

    // 재귀 호출을 사용하지 않고 1부터 n까지의 합을 구하는 메소드
    
    int sum(int n) {
    
        int result = 0;
    
     
    
        for (int i = 1; i <= n; i++) {
    
            result += i;
    
        }
    
     
    
        return result;
    
    }

    이제 재귀 호출을 사용하여 1부터 n까지의 합을 구하는 recursiveSum() 메소드를 만들기

    우선 1부터 4까지의 합을 구하는 알고리즘을 생각

    1. 1~4의 합은 1~3의 합에 4를 더하면 됨

    2. 1~3의 합은 1~2의 합에 3를 더하면 됨

    3. 1~2의 합은 1~1의 합에 2를 더하면 됨\

    4. 1~1의 합은 그냥 1임

    // 위의 알고리즘의 의사 코드(pseudo-code)
    
    시작
    
        1. n이 1이 아니면, n과 1부터 (n-1)까지의 합을 더한 값을 반환함.
    
        2. n이 1이면, 그냥 1을 반환함.
    
    끝
    // 1~n 까지의 합
    
    int recursiveSum(int n) {
    
        if (n == 1) {                 // n이 1이면, 그냥 1을 반환함.
    
            return 1;
    
        }
    
        return n + recursiveSum(n-1); // n이 1이 아니면, n을 1부터 (n-1)까지의 합과 더한 값을 반환함.
    
    }

     

     

     

    출처 : http://www.tcpschool.com/

    'JAVA' 카테고리의 다른 글

    클래스 멤버  (0) 2022.08.08
    제어자  (0) 2022.08.07
    클래스  (0) 2022.08.07
    배열  (0) 2022.08.02
    제어문  (0) 2022.08.02

    댓글