2019-01-07 14:45:39 +00:00
|
|
|
.. index:: ! contract;abstract, ! abstract contract
|
|
|
|
|
|
|
|
.. _abstract-contract:
|
|
|
|
|
|
|
|
******************
|
|
|
|
Abstract Contracts
|
|
|
|
******************
|
|
|
|
|
2022-03-28 20:27:57 +00:00
|
|
|
Contracts must be marked as abstract when at least one of their functions is not implemented or when
|
|
|
|
they do not provide arguments for all of their base contract constructors.
|
|
|
|
Even if this is not the case, a contract may still be marked abstract, such as when you do not intend
|
|
|
|
for the contract to be created directly. Abstract contracts are similar to :ref:`interfaces` but an
|
|
|
|
interface is more limited in what it can declare.
|
|
|
|
|
|
|
|
An abstract contract is declared using the ``abstract`` keyword as shown in the following example.
|
|
|
|
Note that this contract needs to be defined as abstract, because the function ``utterance()`` is declared,
|
|
|
|
but no implementation was provided (no implementation body ``{ }`` was given).
|
2021-06-25 10:25:29 +00:00
|
|
|
|
|
|
|
.. code-block:: solidity
|
2019-01-07 14:45:39 +00:00
|
|
|
|
2020-05-13 15:45:58 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0
|
2020-09-08 08:48:04 +00:00
|
|
|
pragma solidity >=0.6.0 <0.9.0;
|
2019-01-07 14:45:39 +00:00
|
|
|
|
2019-10-23 20:10:12 +00:00
|
|
|
abstract contract Feline {
|
2019-12-03 09:50:53 +00:00
|
|
|
function utterance() public virtual returns (bytes32);
|
2019-01-07 14:45:39 +00:00
|
|
|
}
|
|
|
|
|
2019-09-24 02:10:29 +00:00
|
|
|
Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement
|
2021-06-25 10:25:29 +00:00
|
|
|
all defined functions. The usage of an abstract contract as a base class is shown in the following example:
|
|
|
|
|
|
|
|
.. code-block:: solidity
|
2019-01-07 14:45:39 +00:00
|
|
|
|
2020-05-13 15:45:58 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0
|
2020-09-08 08:48:04 +00:00
|
|
|
pragma solidity >=0.6.0 <0.9.0;
|
2019-01-07 14:45:39 +00:00
|
|
|
|
2019-10-23 20:10:12 +00:00
|
|
|
abstract contract Feline {
|
2020-07-15 09:52:56 +00:00
|
|
|
function utterance() public pure virtual returns (bytes32);
|
2019-01-07 14:45:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
contract Cat is Feline {
|
2020-07-15 09:52:56 +00:00
|
|
|
function utterance() public pure override returns (bytes32) { return "miaow"; }
|
2019-01-07 14:45:39 +00:00
|
|
|
}
|
|
|
|
|
2019-12-05 13:54:48 +00:00
|
|
|
If a contract inherits from an abstract contract and does not implement all non-implemented
|
|
|
|
functions by overriding, it needs to be marked as abstract as well.
|
2019-01-07 14:45:39 +00:00
|
|
|
|
2019-12-05 13:54:48 +00:00
|
|
|
Note that a function without implementation is different from
|
|
|
|
a :ref:`Function Type <function_types>` even though their syntax looks very similar.
|
2019-01-07 14:45:39 +00:00
|
|
|
|
2021-06-25 10:25:29 +00:00
|
|
|
Example of function without implementation (a function declaration):
|
|
|
|
|
|
|
|
.. code-block:: solidity
|
2019-01-07 14:45:39 +00:00
|
|
|
|
|
|
|
function foo(address) external returns (address);
|
|
|
|
|
2021-06-25 10:25:29 +00:00
|
|
|
Example of a declaration of a variable whose type is a function type:
|
|
|
|
|
|
|
|
.. code-block:: solidity
|
2019-01-07 14:45:39 +00:00
|
|
|
|
|
|
|
function(address) external returns (address) foo;
|
|
|
|
|
2019-12-05 13:54:48 +00:00
|
|
|
Abstract contracts decouple the definition of a contract from its
|
|
|
|
implementation providing better extensibility and self-documentation and
|
2019-01-07 14:45:39 +00:00
|
|
|
facilitating patterns like the `Template method <https://en.wikipedia.org/wiki/Template_method_pattern>`_ and removing code duplication.
|
2019-12-05 13:54:48 +00:00
|
|
|
Abstract contracts are useful in the same way that defining methods
|
|
|
|
in an interface is useful. It is a way for the designer of the
|
|
|
|
abstract contract to say "any child of mine must implement this method".
|
2020-04-30 14:11:31 +00:00
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
Abstract contracts cannot override an implemented virtual function with an
|
|
|
|
unimplemented one.
|