블록체인 학습
0 XP

override 키워드

자식 컨트랙트에서 부모의 virtual 함수를 다시 구현할 때는 override 키워드를 붙입니다. 부모가 virtual 로 재정의를 허락하고, 자식이 override 로 실제 재정의를 수행하는 구조입니다. 즉 virtual 과 override 는 항상 짝을 이룹니다. override 가 없으면 컴파일러는 "부모와 이름이 겹치는데 재정의 의도가 없다" 고 보고 오류를 냅니다.

contract Base {
    function greet() public pure virtual returns (string memory) {
        return "Hello from Base";
    }
}
 
contract Child is Base {
    // 부모의 greet 을 새로운 내용으로 재정의합니다.
    function greet() public pure override returns (string memory) {
        return "Hello from Child";
    }
}

시그니처가 정확히 일치해야 한다

재정의하는 함수는 부모와 같은 이름, 같은 매개변수 타입, 같은 반환 타입 이어야 합니다. 하나라도 다르면 재정의가 아니라 별개의 함수(오버로딩)로 취급되거나 컴파일 오류가 납니다. 또한 가시성 규칙도 지켜야 합니다. 예를 들어 external 함수는 public 으로 넓혀 재정의할 수 있지만, 그 반대로 임의로 좁히지는 못합니다.

시그니처가 하나라도 어긋나면 재정의로 인정되지 않습니다. 이름·매개변수·반환 타입을 부모와 똑같이 맞추세요.

어떤 구현이 실행될까?

자식 컨트랙트의 인스턴스에서 greet() 를 호출하면, 부모 버전이 아니라 재정의된 자식 버전 이 실행됩니다. 이렇게 부모의 기본 동작을 자식이 목적에 맞게 바꾸는 것을 다형성(polymorphism) 이라고 부릅니다. 아래 예시에서 Cat 인스턴스의 sound() 는 부모 Animal 의 "..." 가 아니라 "Meow" 를 반환합니다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
 
contract Animal {
    function sound() public pure virtual returns (string memory) {
        return "...";
    }
}
 
contract Cat is Animal {
    function sound() public pure override returns (string memory) {
        return "Meow";
    }
}

재정의 후에도 부모의 원래 동작을 함께 쓰고 싶다면 super 키워드를 활용합니다.

Code Editor
에디터를 불러오는 중...
실행 결과

Run 버튼을 눌러 코드를 실행하세요.