Java/객체 지향

오버로딩(Overloading) & 오버라이딩(Overriding)

늦은산책 2023. 5. 8. 14:50

오버로딩

하나의 클래스 안에 같은 이름의 메소드 여러개를 정의하는것

대표적인 오버로딩으로 println이 있다.

println ( ) 안에 있는 타입을 자동적으로 인식하고 그것을 판별하여 출력한다

 

오버로딩이 성립하기 위한 조건

  1. 메소드 이름이 같아야한다.
  2. 매개변수의 갯수 또는 타입이 달라야한다.
  3. 반환 타입은 영향이 없다.
int add(int a, int b) { return a+b; }
int add(int x, int y) { return x+y; }

메소드 이름이 같다. 매개변수의 갯수와 타입이 같다. 타입은 상관없다 == 오버로딩이 아니다

int add(int a, int b) { return a+b; }
long add(int a, int b) { return (long)(a+b); }

메소드 이름이 같다. 매개변수의 갯수와 타입이 같다. 타입은 상관없다 == 오버로딩이 아니다

long add(int a, long b) { return a+b; }
long add(long a, int b) { return a+b; }

메소드 이름이 같다. 매개변수의 갯수는 같지만 타입이 다르다. 타입은 상관없다 == 오버로딩이 맞다
하지만 여기선 타입이 중요하다. add(3,3)이라고 적는다면 둘중 어느 메소드를 부른지 모호해진다.
그것을 ambiguous라고 한다

 

오버로딩의 적절한 예

class MyMath3 {
    int add(int a, int b) {
        System.out.print("int add(int a, int b) - ");
        return a+b;
    }
    
    long add(long a, long b) {
        System.out.print("long add(long a, long b) - ");
        return a+b;
    }
    
    int add(int[] a) {
        System.out.print("int add(int[] a) - ");
        int result = 0;
        for(int i = 0; i < a.length; i++) {
            result += a[i];
        }
        return result;
    }
}

메소드 3개의 이름이 모두 같지만 매개변수가 모두 다르다.
그럼 메소드를 사용할때 매개변수 타입에 맞게 사용한다면 해당 메소드가 호출되며 사용된다.

오버라이딩

  • 상속받은 조상의 메소드를 자신에 맞게 변경하는것
class Point {
    int x;
    int y;
    
    String getLocation() {
        return "x :" + x + ", y :" + y;
    }
}

class Point3D extends Point {
    int z;
    
    String getLocation() {
        return "x :" + x + ", y:" + y + ", z :" + z;
    }
}
멤버가 z가 생기면서 Point의 getLocation은 Point3D와 맞지 않는 메소드가 되었기때문에 변경이 필요하다

선언부는 변경이 불가능하고 구현부에 적힌 내용만 변경이 가능하다

오버라이딩의 조건

  1. 선언부(반환타입, 메소드 이름, 매개변수 목록)가 조상 클래스의 메소드와 일치해야한다.
  2. 접근제어자를 조상 클래스의 메소드보다 좁은 범위로 변경 할 수 없다.
  3. 예외는 조상 클래스의 메소드보다 많이 선언할 수 없다.

오버로딩 vs 오버라이딩

  • 오버로딩 = 기존에 없는 새로운 메소드를 정의하는것(new)
  • 오버라이딩 = 상속받은 메소드의 내용을 변경하는것(change, modify)
class Parent {
    void parentMethod() {}
}

class Child extends Parent {
    void parentMethod() {}       // 오버라이딩
    void parentMethod(int i) {}  // 오버로딩
    
    void childMethood() {}       // 메소드 정의
    void childMethood(int i) {}  // 오버 로딩
    void childMethood() {}       // 중복 정의 , 에러
}