You can inherit from additional contracts by simply adding a comma and that contract’s name after the first. Add inheritance from ContractC (an error is expected):
Copy
Ask AI
// bad code example, do not usecontract ContractA is ContractB, ContractC { function whoAmExternal() external pure returns (string memory) { return whoAmIInternal(); }}
The error is because both ContractB and ContractC contain a function called whoAmI. As a result, the compiler needs instruction on which to use.
Copy
Ask AI
from solidity:TypeError: Derived contract must override function "whoAmI". Two or more base classes define function with same name and parameter types. --> contracts/Inheritance.sol:21:1: |21 | contract ContractA is ContractB, ContractC { | ^ (Relevant source part starts here and spans across multiple lines).Note: Definition in "ContractC": --> contracts/Inheritance.sol:6:5: |6 | function whoAmI() external pure returns (string memory) { | ^ (Relevant source part starts here and spans across multiple lines).Note: Definition in "ContractB": --> contracts/Inheritance.sol:12:5: |12 | function whoAmI() external pure returns (string memory) { | ^ (Relevant source part starts here and spans across multiple lines).
One method to resolve this conflict is to use the virtual and override keywords to enable you to add functionality to choose which to call.
Add the virtual keyword to the whoAmI function in both ContractC and ContractB.
They must also be made public instead of external, because external functions cannot be called within the contract.
Copy
Ask AI
contract ContractC { function whoAmI() public virtual pure returns (string memory) { return "contract C"; }}contract ContractB { function whoAmI() public virtual pure returns (string memory) { return "contract B"; } // ... additional code}
Add an override function called whoAmI to ContractA:
Copy
Ask AI
// Bad code example, do not usefunction whoAmI() public override pure returns (string memory) { return ContractB.whoAmI();}
You’ll get another error, telling you to specify which contracts this function should override.
Copy
Ask AI
from solidity:TypeError: Function needs to specify overridden contracts "ContractB" and "ContractC". --> contracts/Inheritance.sol:22:32: |22 | function whoAmI() public override pure returns (string memory) { | ^^^^^^^^
Add them both:
Copy
Ask AI
function whoAmI() external override(ContractB, ContractC) pure returns (string memory) { return ContractB.whoAmI();}
Deploy and test. The call will now be back to reporting “contract B”.
Update whoAmI in ContractA to call the appropriate virtual function based on its currentType.
Copy
Ask AI
// Bad code example, do not usefunction whoAmI() public override(ContractB, ContractC) pure returns (string memory) { if(contractType == Type.ContractBType) { return ContractB.whoAmI(); } if(contractType == Type.ContractCType) { return ContractC.whoAmI(); } return "contract A";}
You’ll get errors because the function now reads from state, so it is no longer pure. Update it to view. You’ll also have to update the whoAmIvirtual functions to view to match.
In this lesson, you’ve explored how to use multiple inheritance to import additional functionality into a contract. You’ve also implemented one approach to resolving name conflicts between those contracts.