diff --git a/pages/book/contracts.mdx b/pages/book/contracts.mdx index ba2ea42f..b4ac4f9f 100644 --- a/pages/book/contracts.mdx +++ b/pages/book/contracts.mdx @@ -30,7 +30,7 @@ Each contract can contain: * [Receiver functions](#receiver-functions) * [Internal functions](#internal-functions) -Furthermore, contracts can inherit all the declarations from [traits](/book/types#traits) and override some of their default behaviours. +Furthermore, contracts can inherit all the declarations and definitions from [traits](/book/types#traits) and override some of their default behaviours. If declared or defined in a trait, internal functions and constants can be marked as [virtual or abstract](/book/functions#virtual-and-abstract-functions) and overriden in contracts inheriting from the trait. ### Persistent state variables [#variables] diff --git a/pages/book/functions.mdx b/pages/book/functions.mdx index 308eb6fa..03bfd3d4 100644 --- a/pages/book/functions.mdx +++ b/pages/book/functions.mdx @@ -23,6 +23,31 @@ fun pow(a: Int, c: Int): Int { } ``` +## Virtual and abstract functions + +You can allow the contract inheriting a [traits](/book/types#traits) to modify an internal function, if it has the `virtual` keyword, using `override`. The function can be also marked as `abstract`, in which case the inheriting contract has to define its implementation: + +```tact +trait FilterTrait with Ownable { + virtual fun filterMessage(): Bool { // virtual functions can be overridden by users of this trait + return sender() != self.owner; + } + + abstract fun specialFilter(): Bool; +} + +contract Filter with FilterTrait { + // the trait allows us to override the default behavior + override fun filterMessage(): Bool { + return true; + } + + override fun specialFilter(): Bool { + return true; + } +} +```` + ## Extension function Extension functions allow you to implement extensions for any possible type. diff --git a/pages/book/types.mdx b/pages/book/types.mdx index 6ac92abb..00557f8d 100644 --- a/pages/book/types.mdx +++ b/pages/book/types.mdx @@ -136,7 +136,9 @@ Read more about them on the dedicated page: [Contracts](/book/contracts). ### Traits -Tact doesn't support classical class inheritance, but instead introduces the concept of _traits_, which can be viewed as abstract contracts (like abstract classes in popular object-oriented languages). They have the same structure as [contracts](#contracts), but can't [initialize persistent state variables](/book/contracts#init-function), while allowing to override some of their behaviors. +Tact doesn't support classical class inheritance, but instead introduces the concept of _traits_, which can be viewed as abstract contracts (like abstract classes in popular object-oriented languages). They have the same structure as [contracts](#contracts), but can't [initialize persistent state variables](/book/contracts#init-function). + +A trait can also let the contract inheriting it to override the behavior of its [functions](/book/functions#virtual-and-abstract-functions) and the value of its [constants](/book/constants#virtual-and-abstract-constants). Example of a trait [`Ownable`](/language/libs/ownable#ownable) from [`@stdlib/ownable`](/language/libs/ownable):