[Java] 상속 (2) (feat. overriding)

SeongEon Kim·2022년 4월 26일
0

JAVA

목록 보기
21/52

상속은 상위 클래스의 기능을 하위 클래스에게 물려주는 기능이다.
이때 하위클래스는 상위 클래스의 메소드를 주어진 그대로 사용해야한다면 제약이 상당할 것이다. 이런 제약을 벗어나려면 하위 클래스가 부모 클래스의 기본적인 동작 방법을 변경할 수 있어야 할 것이다. 이를 위해 도입된 기능이 메소드 오버라이딩(overriding)이다. 오버라이딩은 재정의라고도 부를 수 있다.

예를 들어, 상위 클래스에서 sum이라는 메소드를 정의하더라도, 하위 클래스에서 sum이라는 메소드를 재정의하면 재정의된 sum 메소드가 우선순위를 부여받고 실행된다.

단, overriding하기 위해서는 메소드의 리턴 형식이 같아야 한다.
아래 코드를 참고해보자.

class Calculator {
   int left, right;

   public void setOprands(int left, int right) {
       this.left = left;
       this.right = right;
   }

   public void sum() {
       System.out.println(this.left + this.right);
   }

   public void avg() {
       System.out.println((this.left + this.right) / 2);
   }
}

위는 부모 클래스 코드이다.

class SubstractionableCalculator extends Calculator {
     
    public void sum() {
        System.out.println("실행 결과는 " +(this.left + this.right)+"입니다.");
    }
     
    public int avg() {
        return (this.left + this.right)/2;
    }
     
    public void substract() {
        System.out.println(this.left - this.right);
    }
}

위는 자식 클래스 코드이다.

여기서 오류가 발생한다. 왜냐하면, 클래스 Calculator의 메소드 avg는 리턴 타입이 void이다. 그런데 이것을 상속한 클래스 SubstractionableCalculator의 리턴 타입은 int이다. 즉, 메소드의 리턴 형식이 다른 것이다.

따라서 아래의 코드처럼 수정해야 한다.

class Calculator {
    int left, right;
 
    public void setOprands(int left, int right) {
        this.left = left;
        this.right = right;
    }
 
    public void sum() {
        System.out.println(this.left + this.right);
    }
 
    public int avg() {
    //기존 코드 void에서 int로 수정되었다.
        return ((this.left + this.right) / 2);
    }
}


class SubstractionableCalculator extends Calculator {
     
    public void sum() {
        System.out.println("실행 결과는 " +(this.left + this.right)+"입니다.");
    }
     
    public int avg() {
        return ((this.left + this.right) / 2);
    }
     
    public void substract() {
        System.out.println(this.left - this.right);
    }
}

오버라이딩을 하기 위해서는 아래의 조건을 충족시켜야 한다.

1) 메소드의 이름
2) 메소드 매개변수의 숫자와 데이터 타입 그리고 순서
3) 메소드의 리턴 타입

이렇게 메소드의 형태를 정의하는 사항들을 통틀어서 메소드의 서명(signature)라고 한다. 위의 에러는 메소들 간의 서명이 달라서 생긴 문제인 것이다.

하지만 바로 위의 코드는 코드 상 에러는 없으나 코드 중복이 있어서 비효율적이다. super를 사용해 중복을 해결하면 아래와 같다.

class Calculator {
    int left, right;
 
    public void setOprands(int left, int right) {
        this.left = left;
        this.right = right;
    }
 
    public void sum() {
        System.out.println(this.left + this.right);
    }
 
    public int avg() {
        return ((this.left + this.right) / 2);
    }
}

class SubstractionableCalculator extends Calculator {
     
    public void sum() {
        System.out.println("실행 결과는 " +(this.left + this.right)+"입니다.");
    }
     
    public int avg() {
        return super.avg();
    }
     
    public void substract() {
        System.out.println(this.left - this.right);
    }
}
profile
꿈을 이루는 사람

0개의 댓글