diff --git a/docs/contracts.rst b/docs/contracts.rst index 121c4de0edd9..d91de8d997d4 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -818,9 +818,9 @@ Additional Resources for Understanding Events Inheritance *********** -Solidity supports multiple inheritance by copying code including polymorphism. +Solidity supports multiple inheritance including polymorphism. -All function calls are virtual, which means that the most derived function +All function calls (this includes external and internal calls) are virtual, which means that the most derived function is called, except when the contract name is explicitly given. When a contract inherits from multiple contracts, only a single @@ -831,11 +831,90 @@ The general inheritance system is very similar to `Python's `_, especially concerning multiple inheritance. +Declaring two elements (for example functions) of the same name in +two different contracts that are part of the same inheritance hierarchy, +is called _overriding_. Declaring two elements of the same name in the +same contract is called _overloading_. + +If a function is callable on a contract, it must also be callable in the derived contract. +This means that visibility of functions cannot be restricted, but it +can be extended. Mutability in turn, can be restricted, but not extended. + +The visibility can change from external to public, but not from public +to external or from external to internal. Functions that are marked ``view`` in the +super contract, can be marked ``pure`` in the derived contract, but not the other +way around: + ++---------------------+------------------------------+ +| A function | ... can be overridden by a | +| with visibility ... | function with visibility ... | ++=====================+==============================+ +| ``external`` | ``external`` or ``public`` | ++---------------------+------------------------------+ +| ``public`` | ``public`` | ++---------------------+------------------------------+ +| ``internal`` | ``internal`` or ``public`` | ++---------------------+------------------------------+ +| ``private`` | (none) | ++---------------------+------------------------------+ + ++---------------------+---------------------------------+ +| A function | ... can be overridden by a | +| with mutability ... | function with mutability ... | ++=====================+=================================+ +| ``payable`` | ``payable`` | ++---------------------+---------------------------------+ +| (default) | (default), ``view`` or ``pure`` | ++---------------------+---------------------------------+ +| ``view`` | ``view`` or ``pure`` | ++---------------------+---------------------------------+ +| ``pure`` | ``pure`` | ++---------------------+---------------------------------+ + +If a function overrides a function from a super contract, it needs the ``override`` specifier, +everything else is treated as an error. + +An external function (but not a function of any other visibility) can be overridden by a public +state variable. This means that the public state variable also needs the ``override`` keyword. + +Any other use of overriding between functions, modifiers, state variable or user-defined types +(meaning overriding a function with a modifier or a state variable with a function, etc.) is disallowed. +This means that you cannot declare a struct which has the same name as a function in super contract. + +Modifiers are treated in much the same way as functions: They use virtual lookup, require the +``override`` specifier, can use overloading and can have a missing implementation. + +It is an error for multiple contracts in an inheritance hierarchy to have a member of the same name, +unless there is a single contract (``C``) which declares the member and all other contracts +that also declare the member inherit from it (directly or indirectly), all declarations +of that member except for the one in ``C`` use the ``override`` keyword, the members +are either all modifiers or all functions and potentially state variables, all inheritance +relations are compatible with +regards to visibility and state mutability as per the above rules and all have exactly the same +parameter and return types or, if there are functions or modifiers of the same name +declared in ``C`` with different parameters, then all of these functions or modifiers +have to be re-stated in all derived contracts that declare at least one of these +functions or modifiers. + +This in particular means that `private` members are not hidden from this mechanism and that +overriding and overloading is incompatible. It also means that it is disallowed to inherit +members of the same name that come from different base contracts unless they share a common +base contract that defines the function to be overridden. + +The above rule also means that it is illegal to inherit functions of the same name +from two base contracts who do not derive from the same base contract. It is only allowed +if there is a common base contract which also defines a function of this name. In that case, +the most derived contract can even override the function again. + +As it is often useful to inherit the natspec comments for functions from super contracts. +This has to be done explicitly using the ``@inherit`` natspec tag. This tag +will inherit all properties that are not re-defined in the function of the derived contract. + Details are given in the following example. :: - pragma solidity ^0.4.16; + pragma solidity ^0.5.0; contract owned { function owned() { owner = msg.sender; } @@ -1116,13 +1195,13 @@ facilitating patterns like the `Template method