What is inheritance in Solidity?
Solidity is a popular programming language for creating smart contracts. It is one of the most used programming languages for developing smart contracts on Ethereum and EVM-compatible blockchains. One of the important highlights of Solidity is the fact that it features the traits of object-oriented programming languages. Therefore, Solidity inheritance is definitely one of the features that you would find during the implementation of Solidity of smart contract development.
Inheritance refers to the ability of an object to inherit certain functions, behaviors, and variables from other objects. The applications of inheritance in smart contract development with Solidity help in creating smart contracts based on another contract. It could help in extending the attributes and traits of a specific contract to derived contracts. Let us learn more about inheritance and its role in Solidity with examples.
Want to get an in-depth understanding of Solidity concepts? Enroll now in the Solidity Fundamentals Course
What is Inheritance?
Solidity programming involves development of smart contracts with programming. One of the unique highlights of Solidity is the fact that it supports inheritance. You can find answers to “Does Solidity have inheritance?” in the flexibility for expanding usefulness of smart contracts in Solidity. It is also important to remember that Solidity supports single-rules inheritance alongside multiple inheritance by employing polymorphism. Solidity enables smart contract inheritance with the flexibility for incorporating traits of multiple contracts in one contract.
You can find different types of inheritance in Solidity, such as single, multiple, hierarchical, and multi-level inheritance. Single inheritance points to the situations in which one smart contract inherits the properties of another contract. Multiple inheritance is visible in scenarios where a single contract inherits the traits of multiple contracts simultaneously. Hierarchical inheritance refers to the cases where parent contracts could have more than one child contract. Multi-level inheritance is a variant of single inheritance, albeit with different levels of relationship between the child and parent contracts.
Learn about the fundamentals of smart contracts & solidity with Solidity & Smart Contracts E-Book
Importance of Inheritance in Solidity
The discussions about inheritance traits of Solidity also draw references to its significance. Whether it is Solidity multiple inheritance or single inheritance, you can find different benefits. First of all, you must note that inheritance is one of the key traits of object-oriented programming languages.
Developers can rely on inheritance to improve the functionality of a program by isolating code, eliminating dependencies, and increasing reusability of existing code. Interestingly, Solidity offers support for inheritance between smart contracts alongside inheritance of multiple contracts into one contract.
Developers could expand the attributes and properties of a parent contract to the derived contracts. In addition, Solidity inheritance example also showcases the facility for modifying the attributed and traits of derived contracts through overriding. Derived contracts could access all the non-private members, such as state variables and internal methods. At the same time, it is also important to note that such functionalities are not permitted in Solidity. When you call functions by using super in multiple inheritance, the most derived contract would have the first preference.
You should also know about the optional availability of Solidity inheritance constructor and the fact that smart contracts have default constructors. Developers could specify constructor arguments in two different ways. The importance of inheritance also points towards marking different contracts associated with a parent-child dynamic. On top of it, the similarity between Solidity and Python in terms of inheritance rules also provides flexibility for transition of programmers to smart contract development tasks.
Excited to learn about the key elements of Solidity? Check out Introduction To Solidity Presentation
Working of Inheritance
The term ‘inheritance’ refers to the process in which the properties and assets of parents pass to the children. You must compare Solidity inheritance with similar relationships. The base contract is the contract that helps other contracts in inheriting features. On the other hand, the derived contract is the contract that inherits features of the base contract.
The base contract and derived contracts are described as parent and child contracts. However, the working of inheritance in Solidity uses only public and internal modifiers. Here are some of the important highlights in the working of inheritance for Solidity smart contracts.
- Apart from internal methods and state variables, derived contracts could access all the other non-private members in smart contracts. However, derived contracts in Solidity do not have the permissions.
- In any Solidity inheritance example, you must notice that overriding functions can work only if the function signature remains constant.
- Developers can access the functions of a super contract by using the ‘super’ keyword or the super contract name.
- Solidity could present failure in compilation in scenarios where the output parameters do not align with the input values.
- In the event of Solidity multiple inheritance, the function calls with ‘super’ keyword would prioritize the most derived contracts.
Build your identity as a certified blockchain expert with 101 Blockchains’ Blockchain Certifications designed to provide enhanced career prospects.
Polymorphism in Solidity Inheritance
The working and importance of inheritance in object-oriented programming ensures promising advantages for the adoption of inheritance in smart contract development. On top of it, you can also respond to questions like “Does Solidity have inheritance?” by pointing out the implications of polymorphism. Polymorphism helps in ensuring multiple inheritance in the popular smart contract programming language. The working mechanism of polymorphism could help you understand how inheritance works in different ways for Solidity.
Polymorphism implies that external and internal function calls would always execute functions with the same parameter types and name as the most derived contract in hierarchy of inheritance. Developers can enable polymorphism explicitly on each function within the hierarchy by leveraging the ‘override’ and ‘virtual’ keywords.
It is also important to call functions in the higher echelons of inheritance hierarchy by providing explicit specifications for the contract. You can provide explicit specifications for inheritance in Solidity by leveraging the “ContractName.functionName()”. You can also utilize the “super.functionName()” when you want to call functions that are one level higher in a flat inheritance hierarchy.
The implementation of inheritance results in the creation of one smart contract on the blockchain. In addition, all the code from base contracts is compiled within the created contract. It would imply that all the internal calls to base contract functions can utilize internal function calls. For example, the “super.f(…)” call would utilize JUMP instead of a message call.
The review of polymorphism for Solidity multiple inheritance also draws attention to errors like state variable shadowing. Only the derived contracts have permission to declare a state variable in the event of a lack of visible state variable with same name in any base contract.
Curious to understand the complete smart contract development lifecycle? Enroll now in Smart Contracts Development Course
What is Function Overriding?
The guides to inheritance in Solidity would be incomplete without focusing on function overriding. Inheriting contracts could override base functions, which are classified as ‘virtual,’ for changing their behavior. The overriding function should utilize the ‘override’ keyword in the function header. Here is a Solidity inheritance example to showcase a demonstration of function overriding.
pragma solidity >=0.5.0 <0.7.0; contract Base function foo() virtual public contract Middle is Base contract Inherited is Middle function foo() public override
In the case of multiple inheritance for Solidity contracts, the most derived base contracts responsible for defining the same function should be specified clearly with the ‘override’ keyword. You must specify all base contracts defining the same function without being overridden by other base contracts. On top of it, contracts that inherit same function from different unrelated base contracts must explicitly override the function.
The official documentation for Solidity inheritance provides additional insights on function overriding. For example, you don’t need an explicit override specifier in two situations. The first situation involves definition of a function in the common base contract. You would not need an explicit override specifier when you have a unique function for a common base contract capable of overriding other functions.
Should you override functions inherited from multiple base contracts in every case? No, you don’t need direct or indirect function overriding in certain scenarios where all override paths for the signature include a base contract. In addition, it is also important to verify whether the base ensures function implementation without mentioning any function with the signature in the paths from current contract to base contract. Another scenario for avoiding function overriding in Solidity multiple inheritance involves a base contract not implementing the function. Such scenarios also involve mentioning the function at least once in all paths from current contract to the base contract.
You might be wondering about the definition of an override path in function overriding. Override path for a specific signature refers to the path in the inheritance graph starting at the current contract. The endpoint of the override path is a contract that mentions a function that has a signature that does not have overriding capabilities.
Without marking a function that overrides in the ‘virtual’ form, derived contracts could not modify the function behavior. On top of it, you must also note that public state variables are capable of overriding external functions. It is possible when the parameter alongside return types of the function could align with the ‘getter’ function in the variable.
Want to know the real-world examples of smart contracts and understand how you can use it for your business? Check the presentation on Examples Of Smart Contracts
What is Modifier Overriding?
Another crucial aspect in discussions about inheritance in Solidity points to modifier overriding. Function modifiers have the capability of overriding each other. Modifier overriding works in a similar fashion as function overriding without any overloading for modifiers. It is important to note that the ‘virtual’ keyword should be used for the overridden modifier. In addition, the overriding modifier must also feature the ‘override’ keyword. In the event of multiple inheritance, it is important to provide explicit specifications for all the direct base contracts.
Role of Constructors in Inheritance
The discussions about inheritance for smart contracts in Solidity would also focus on constructors. What is a Solidity inheritance constructor, and what is their importance? Constructors are optional functions that are declared in the ‘constructor’ keyword and executed at the time of contract development. It serves a crucial role in facilitating effective execution of contract initialization code. State variables must be initialized to specified values for inline initialization or zero before the execution of constructor code.
After deploying a constructor, the final code for the smart contract can be deployed on blockchain network. Any Solidity inheritance example with constructors can show you that deploying the code could result in additional gas costs at the same level as length of the code. The contract code features all the functions included in the public interface. In addition, it also features functions that can be accessible through simple function calls. The contract code does not include constructor code or the internal functions that could be called only from the constructor.
It is also important to note that constructor functions can be classified as ‘internal’ or ‘public.’ Without any constructor, the contract would assume the default Solidity inheritance constructor along the lines of ‘constructor() public .’ Here is an example of the use of constructors in Solidity smart contracts.
pragma solidity >=0.5.0 <0.7.0; contract A uint public a; constructor(uint _a) internal a = _a; contract B is A(1) constructor() public
The constructor defined as ‘internal’ could help in marking the contract as an ‘abstract’ one. Before the Solidity version 0.4.22, constructors had to be defined in the form of functions that have similar names as the contract. After version 0.5.0, the syntax for constructors has been deprecated.
Excited to learn about the different ways to create a smart contract using a solidity programming language? Read here How To Create A New Contract From Another Contract In Solidity now!
Is it Possible to Inherit Different Types of Members with Same Name?
You should also reflect on answers for ‘Does Solidity have inheritance?’ with references to possibilities of inheriting different types of members with same name. Developers might encounter errors when specific pairs in smart contracts share the same name owing to inheritance. The pairs include function-modifier, event-modifier, and function-event pairs. On the other hand, you can also find an exception in this case, as a state variable getter could override external functions.
Start your journey to become a smart contract developer or architect with an in-depth overview of smart contract fundamentals with Smart Contracts Skill Path
Conclusion
The introduction to inheritance in Solidity provides proof of the flexibility for reusing smart contract code. It is an essential element for smart contract developers to recreate successful smart contract functionalities in their applications. On top of it, the features for function overriding and modifier overriding enable developers to introduce custom functionalities.
The support for Solidity multiple inheritance through polymorphism can play a crucial role in empowering scalability for smart contracts. At the same time, you must also notice the importance of constructors for initialization of smart contract code. Learn more about Solidity fundamentals and create your expertise in smart contract development right now.