참조 변수의 다형성: 자바에서는 다형성을 위해 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하고 있다. 이때 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 같거나 적어야 참조할 수 있다.
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 : 부모 클래스 타입의 참조 변수로도 자식 클래스 타입의 인스턴스를 참조할 수 있다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 적기 때문이다. //오류 : 하지만 반대의 경우인 자식 클래스 타입의 참조 변수로는 부모 클래스 타입의 인스턴스를 참조할 수 없다. 참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문이다.

같은 이름의 메서드를 정의할 수 있다.
매개변수의 타입, 개수, 순서가 달라야 한다.
반환 타입(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.나이 = 나이;
}
}
사람(String 이름, int 나이) {
//가능
this.이름 = 이름; // 클래스 멤버 변수 이름 = 매개변수 이름
this.나이 = 나이;
//오류 발생. 이 경우, 클래스 멤버 변수는 초기화되지 않고 **기본값(참조형: null, 기본형: 0)**을 유지하게 된다.
이름 = 이름; // 매개변수 이름 = 매개변수 이름 (아무 의미 없음)
나이 = 나이; // 매개변수 나이가 자기 자신을 참조하므로, 멤버 변수는 초기화되지 않음
}