다중 상속
Solidity 는 한 컨트랙트가 여러 부모를 동시에 상속 받는 다중 상속을 지원합니다. is 뒤에 부모 컨트랙트를 쉼표로 나열하면, 자식은 나열한 모든 부모의 멤버를 물려받습니다. 다중 상속은 서로 독립적인 기능들을 조합할 때 강력하지만, 부모들에게 같은 함수가 있으면 "어느 부모의 구현을 따를 것인가" 라는 충돌(diamond problem)이 생길 수 있어 규칙을 정확히 알아야 합니다.
contract A { }
contract B { }
contract C is A, B {
// A 와 B 의 멤버를 모두 물려받습니다.
}여러 부모에 같은 virtual 함수가 있으면, 자식은 override(A, B) 처럼 부모들을 모두 명시해
재정의해야 합니다.
C3 선형화와 상속 순서
다중 상속에서는 상속 순서가 중요합니다. Solidity 는 C3 선형화(C3 linearization) 규칙에 따라 부모들을 하나의 일렬 순서로 정렬합니다. 관례상 부모는 가장 기초가 되는 것(왼쪽)부터 가장 파생된 것(오른쪽) 순으로 적습니다. 순서가 잘못되면 컴파일러가 선형화에 실패해 오류를 냅니다. 이렇게 정렬된 순서는 생성자 실행 순서와 super 호출의 진행 방향을 결정합니다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Walks {
function move() public pure virtual returns (string memory) {
return "walk";
}
}
contract Swims {
function swim() public pure virtual returns (string memory) {
return "swim";
}
}
contract Duck is Walks, Swims {
// move() 와 swim() 을 모두 사용할 수 있습니다.
}super 와 선형화의 관계
다중 상속에서 super 는 단순히 "부모" 가 아니라 C3 선형화 가 정한 다음 컨트랙트 를 가리킵니다. 따라서 같은 함수를 여러 부모가 override 했을 때, 각 단계에서 super 를 호출하면 선형화 순서를 따라 모든 구현이 빠짐없이 연쇄 실행됩니다. 이것이 OpenZeppelin 의 여러 모듈을 동시에 상속해도 각 모듈의 로직이 충돌 없이 합쳐지는 원리입니다.
충돌하는 함수를 재정의할 때는 override(부모1, 부모2) 로 관련 부모를 모두 적고, 필요하면 super
로 부모 구현들을 연결하세요.