Solidity – How to Use ‘super’ When Overriding Multiple Parents in Solidity Contracts

contract-developmentsolidity

When inheriting from multiple contracts with the same method sometimes I am asked (by the IDE and the compiler) to override a function which is declared in both contracts.

This usually happens when the "parents" my contract is inheriting from implement the IERC165 interface.
In this case I have some code which looks like the following lines (this is ERC721):

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

In this example this function overrides an implementation contract and an abstract one, but in other cases I had to implement a function which overrides two implementation contracts.

In that situation what does the "super" keyword refer to?
I am confused because it seems like super refer to a father contract, but in this case there are more than one, so I don't know how to determine to which one super refers to.

Thanks

Best Answer

This answer has some good insights regarding this situation:

"Solidity uses the same linearization algorithm as python (C3). So super would refer to the next highest class in the linearization. (caution: in python you read the classes from left to right from highest to lowest; in solidity you read from right to left to go from highest to lowest)."

If you need to call both inherited contracts' function, you can explicitly do so instead of using super, where your contract inherits from ContractB and ContractA:

ContractB.func();
ContractA.func();