[TIL] 자바의 오버로딩, this생성자

냠냠빈·2024년 11월 22일

자바의 오버로딩(Overloading)이란?

  • 오버로딩이란 같은 이름의 메서드를 매개변수의 타입, 개수, 순서를 다르게 정의하여 하나의 이름으로 여러 기능을 수행할 수 있도록 만드는 것을 의미한다. 오버로딩은 자바의 다형성(Polymorphism)을 지원하는 중요한 개념이다.
    • 여기서 다형성이란? 다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미한다. 자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현한다.

      참조 변수의 다형성: 자바에서는 다형성을 위해 부모 클래스 타입의 참조 변수자식 클래스 타입의 인스턴스를 참조할 수 있도록 하고 있다. 이때 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 같거나 적어야 참조할 수 있다.

      class Parent { ... }
      class Child extends Parent { ... }
      ...
      Parent p1 = new Parent(); // 가능1
      Child c1 = new Child();   // 가능2
      Parent p2 = new Child();  // 가능3
      Child c2 = new Parent();  // 오류 발생.
      //가능 1,2 : 특정 타입의 참조 변수로는 당연히 같은 타입의 인스턴스를 참조할 수 있다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수와 같기 때문이다.
      //가능 3 : 부모 클래스 타입의 참조 변수로도 자식 클래스 타입의 인스턴스를 참조할 수 있다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 적기 때문이다.
      //오류 : 하지만 반대의 경우인 자식 클래스 타입의 참조 변수로는 부모 클래스 타입의 인스턴스를 참조할 수 없다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문이다.

      출처: https://tcpschool.com/java/java_polymorphism_concept

  • 오버로딩 예시 : 코스 자바로 배우는 프로그래밍 - 오버로딩

오버로딩의 특징

  • 같은 이름의 메서드를 정의할 수 있다.

  • 매개변수의 타입, 개수, 순서가 달라야 한다.

  • 반환 타입(return type)은 오버로딩 조건에 영향을 주지 않는다.

  • 컴파일러가 메서드 호출 시 매개변수의 타입과 개수를 보고 적절한 메서드를 선택한다.

    • 오버로딩의 예시
    class Calculator {
          // 1. 매개변수의 개수가 다른 경우
          int add(int a, int b) {
          	return a + b;
          }
    
          int add(int a, int b, int c) {
              return a + b + c;
          }
    
          // 2. 매개변수의 타입이 다른 경우
          double add(double a, double b) {
              return a + b;
          }
    
          // 3. 매개변수의 순서가 다른 경우
          String add(String a, int b) {
              return a + b;
          }
    
          String add(int b, String a) {
              return b + a;
          }
    }
      
    public class Main {
    		public static void main(String[] args) {
          	    Calculator calc = new Calculator();
    
                // 매개변수 개수에 따라 호출되는 메서드가 달라진다.
                System.out.println(calc.add(1, 2));       // 출력: 3
                System.out.println(calc.add(1, 2, 3));    // 출력: 6
    
                // 매개변수 타입에 따라 호출되는 메서드가 달라진다.
                System.out.println(calc.add(1.5, 2.5));   // 출력: 4.0
    
                // 매개변수 순서에 따라 호출되는 메서드가 달라진다.
                System.out.println(calc.add("Hello", 5)); // 출력: Hello5
                System.out.println(calc.add(5, "World")); // 출력: 5World
        	}
    }

오버로딩의 조건

  • 반드시 메서드 이름이 같아야 한다.
  • 매개변수의 타입, 개수, 순서 중 하나라도 달라야 한다.
  • 반환 타입은 오버로딩을 구분하는 기준이 될 수 없다.
// 잘못된 오버로딩: 반환 타입만 다름
class Test {
    int example(int a) {
        return a;
    }

    // 컴파일 에러: 반환 타입만 다르면 오버로딩으로 인식되지 않음
    double example(int a) {
        return a * 1.0;
    }
}

생성자 오버로딩

  • 생성자(Constructor)에서도 오버로딩을 적용할 수 있는데, 이는 다양한 방법으로 객체를 생성할 수 있도록 도와준다.

    class Person {
        String name;
        int age;
    
        // 기본 생성자
        Person() {
            this.name = "Unknown";
            this.age = 0;
        }
    
        // 매개변수가 있는 생성자
        Person(String name) {
            this.name = name;
            this.age = 0;
        }
    
        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Person p1 = new Person();                // Unknown, 0
            Person p2 = new Person("Alice");         // Alice, 0
            Person p3 = new Person("Bob", 25);       // Bob, 25
        }
    }

생성자란?

  • 생성자(Constructor)는 객체 지향 프로그래밍에서 객체가 생성될 때 초기화시켜주는 함수를 의미한다. 필요에 따라 객체 내 데이터에 특정한 값을 입력하기도 한다. 위의 코드에서 Person클래스의 Person이라는 이름의 생성자가 두 가지 있었는데 두번째에는 매개변수를 전달하여 Person클래스의 인스턴스 변수 name, age에 값을 저장할 수 있다.

    생성자 조건

    • 생성자는 자료형을 갖지 않는다. void조차 아니다. 그냥 클래스 이름으로 생성한다.

    • 생성자는 클래스와 이름이 동일해야한다. 가끔 생성자와 클래스의 이름을 다르게 설정하는 경우가 있는데 이럴 경우 단순하게 메서드가 되어 동작에 오류를 일으키거나 컴파일 에러가 난다.
      나무위키-생성자

    • this.변수(클래스 멤버 변수 이름)와 매개변수의 이름이 다르다면 this를 생략하고 변수 = 매개변수; 이렇게 작성해도 되지만 클래스 멤버 변수 이름과 매개변수의 이름이 같다면 this는 생략할 수 없다.

      예시:

      public class Main {
      		public static void main(String[] args) {
              	사람 a사람1 = new 사람();
              	사람 a사람2 = new 사람("홍길순", 55);
          	}
      }
      
      class 사람 {
      		String 이름;
        	    int 나이;
      
            	사람() {
                this.이름 = "홍길동";
                this.나이 = 22;
              }
      
              사람(String 이름, int 나이) {
                this.이름 = 이름;
                this.나이 = 나이;
              }
      }
      • 이 코드에서 this를 생략하면 안 되는 이유는 매개변수 이름(지역 변수)클래스의 필드 이름(멤버 변수)이 동일하기 때문이다. this를 사용하지 않으면, 지역 변수(매개변수)가 우선적으로 참조되어 의도한 클래스의 멤버 변수를 초기화할 수 없게 된다.
      • 매개변수가 있는 생성자
         사람(String 이름, int 나이) {
         
          //가능
          this.이름 = 이름; // 클래스 멤버 변수 이름 = 매개변수 이름
          this.나이 = 나이;
          
          //오류 발생. 이 경우, 클래스 멤버 변수는 초기화되지 않고 **기본값(참조형: null, 기본형: 0)**을 유지하게 된다.
          이름 = 이름; // 매개변수 이름 = 매개변수 이름 (아무 의미 없음)
          나이 = 나이; // 매개변수 나이가 자기 자신을 참조하므로, 멤버 변수는 초기화되지 않음
          }

profile
다 먹어버릴거야!

0개의 댓글