mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-04 14:11:02 +03:00
GDScript: Document abstract and variadic functions
This commit is contained in:
@@ -324,6 +324,7 @@ class GDScriptLexer(RegexLexer):
|
|||||||
"is_instance_of",
|
"is_instance_of",
|
||||||
"len",
|
"len",
|
||||||
"load",
|
"load",
|
||||||
|
"ord",
|
||||||
"preload",
|
"preload",
|
||||||
"print_debug",
|
"print_debug",
|
||||||
"print_stack",
|
"print_stack",
|
||||||
@@ -396,6 +397,7 @@ class GDScriptLexer(RegexLexer):
|
|||||||
words(
|
words(
|
||||||
(
|
(
|
||||||
# modules/gdscript/doc_classes/@GDScript.xml
|
# modules/gdscript/doc_classes/@GDScript.xml
|
||||||
|
"@abstract",
|
||||||
"@export",
|
"@export",
|
||||||
"@export_category",
|
"@export_category",
|
||||||
"@export_color_no_alpha",
|
"@export_color_no_alpha",
|
||||||
@@ -404,6 +406,7 @@ class GDScriptLexer(RegexLexer):
|
|||||||
"@export_enum",
|
"@export_enum",
|
||||||
"@export_exp_easing",
|
"@export_exp_easing",
|
||||||
"@export_file",
|
"@export_file",
|
||||||
|
"@export_file_path",
|
||||||
"@export_flags",
|
"@export_flags",
|
||||||
"@export_flags_2d_navigation",
|
"@export_flags_2d_navigation",
|
||||||
"@export_flags_2d_physics",
|
"@export_flags_2d_physics",
|
||||||
|
|||||||
@@ -1572,6 +1572,62 @@ Lambda functions cannot be declared static.
|
|||||||
|
|
||||||
See also `Static variables`_ and `Static constructor`_.
|
See also `Static variables`_ and `Static constructor`_.
|
||||||
|
|
||||||
|
Variadic functions
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A variadic function is a function that can take a variable number of arguments.
|
||||||
|
Since Godot 4.5, GDScript supports variadic functions. To declare a variadic function,
|
||||||
|
you need to use the *rest parameter*, which collects all the excess arguments into an array.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
func my_func(a, b = 0, ...args):
|
||||||
|
prints(a, b, args)
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
my_func(1) # 1 0 []
|
||||||
|
my_func(1, 2) # 1 2 []
|
||||||
|
my_func(1, 2, 3) # 1 2 [3]
|
||||||
|
my_func(1, 2, 3, 4) # 1 2 [3, 4]
|
||||||
|
my_func(1, 2, 3, 4, 5) # 1 2 [3, 4, 5]
|
||||||
|
|
||||||
|
A function can have at most one rest parameter, which must be the last one in the parameter list.
|
||||||
|
The rest parameter cannot have a default value. Static and lambda functions can also be variadic.
|
||||||
|
|
||||||
|
Static typing works for variadic functions too. However, typed arrays are currently not supported
|
||||||
|
as a static type of the rest parameter:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# You cannot specify `...values: Array[int]`.
|
||||||
|
func sum(...values: Array) -> int:
|
||||||
|
var result := 0
|
||||||
|
for value in values:
|
||||||
|
assert(value is int)
|
||||||
|
result += value
|
||||||
|
return result
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Although you can declare functions as variadic using the rest parameter, unpacking parameters
|
||||||
|
when calling a function using *spread syntax* that exists in some languages (JavaScript, PHP)
|
||||||
|
is currently not supported in GDScript. However, you can use ``callv()`` to call a function
|
||||||
|
with an array of arguments:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
func log_data(...values):
|
||||||
|
# ...
|
||||||
|
|
||||||
|
func other_func(...args):
|
||||||
|
#log_data(...args) # This won't work.
|
||||||
|
log_data.callv(args) # This will work.
|
||||||
|
|
||||||
|
Abstract functions
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
See `Abstract classes and methods`_.
|
||||||
|
|
||||||
Statements and control flow
|
Statements and control flow
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
@@ -2047,7 +2103,7 @@ If you want to use ``extends`` too, you can keep both on the same line:
|
|||||||
Named classes are globally registered, which means they become available to use
|
Named classes are globally registered, which means they become available to use
|
||||||
in other scripts without the need to ``load`` or ``preload`` them:
|
in other scripts without the need to ``load`` or ``preload`` them:
|
||||||
|
|
||||||
.. code-block:: gdscript
|
::
|
||||||
|
|
||||||
var player
|
var player
|
||||||
|
|
||||||
@@ -2070,30 +2126,45 @@ in other scripts without the need to ``load`` or ``preload`` them:
|
|||||||
|
|
||||||
.. _doc_gdscript_basics_abstract_class:
|
.. _doc_gdscript_basics_abstract_class:
|
||||||
|
|
||||||
Registering abstract classes
|
Abstract classes and methods
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Since Godot 4.5, you can register abstract classes using the ``abstract`` keyword.
|
Since Godot 4.5, you can define abstract classes and methods using
|
||||||
An abstract class is a class that cannot be instantiated directly. Instead, it
|
the ``@abstract`` annotation.
|
||||||
is meant to be subclassed by other classes. Attempting to instantiate
|
|
||||||
|
An abstract class is a class that cannot be instantiated directly.
|
||||||
|
Instead, it is meant to be inherited by other classes. Attempting to instantiate
|
||||||
an abstract class will result in an error.
|
an abstract class will result in an error.
|
||||||
|
|
||||||
|
An abstract method is a method that has no implementation. Therefore, a newline
|
||||||
|
or a semicolon is expected after the function header. This defines a contract that
|
||||||
|
inheriting classes must conform to, because the method signature must be compatible
|
||||||
|
when overriding.
|
||||||
|
|
||||||
|
Inheriting classes must either provide implementations for all abstract methods,
|
||||||
|
or the inheriting class must be marked as abstract. If a class has at least one
|
||||||
|
abstract method (either its own or an unimplemented inherited one),
|
||||||
|
then it must also be marked as abstract. However, the reverse is not true:
|
||||||
|
an abstract class is allowed to have no abstract methods.
|
||||||
|
|
||||||
|
.. tip::
|
||||||
|
|
||||||
|
If you want to declare a method as optional to be overridden, you should use
|
||||||
|
a non-abstract method and provide a default implementation.
|
||||||
|
|
||||||
For example, you could have an abstract class called ``Shape`` that defines
|
For example, you could have an abstract class called ``Shape`` that defines
|
||||||
a method called ``draw()``. You can then create subclasses like ``Circle``
|
an abstract method called ``draw()``. You can then create subclasses like ``Circle``
|
||||||
and ``Square`` that implement the ``draw()`` method in their own way.
|
and ``Square`` that implement the ``draw()`` method in their own way.
|
||||||
This allows you to define a common *interface* for all shapes without
|
This allows you to define a common *interface* for all shapes without
|
||||||
having to implement all the details in the abstract class itself:
|
having to implement all the details in the abstract class itself:
|
||||||
|
|
||||||
.. code-block:: gdscript
|
::
|
||||||
|
|
||||||
abstract class Shape:
|
@abstract class Shape:
|
||||||
func draw():
|
@abstract func draw()
|
||||||
# It is possible for subclasses to call the parent class method using `super()`.
|
|
||||||
# In this example, we won't use `super()` to call the parent class method,
|
|
||||||
# so we can leave this method empty.
|
|
||||||
pass
|
|
||||||
|
|
||||||
# This is a concrete (non-abstract) subclass of Shape.
|
# This is a concrete (non-abstract) subclass of Shape.
|
||||||
|
# You **must** implement all abstract methods in concrete classes.
|
||||||
class Circle extends Shape:
|
class Circle extends Shape:
|
||||||
func draw():
|
func draw():
|
||||||
print("Drawing a circle.")
|
print("Drawing a circle.")
|
||||||
@@ -2102,16 +2173,17 @@ having to implement all the details in the abstract class itself:
|
|||||||
func draw():
|
func draw():
|
||||||
print("Drawing a square.")
|
print("Drawing a square.")
|
||||||
|
|
||||||
Both subclasses and classes created using ``class_name`` can be abstract. This
|
Both inner classes and classes created using ``class_name`` can be abstract.
|
||||||
example creates two abstract classes, one of which is a subclass of another
|
This example creates two abstract classes, one of which is a subclass of another
|
||||||
abstract class:
|
abstract class:
|
||||||
|
|
||||||
.. code-block:: gdscript
|
::
|
||||||
|
|
||||||
abstract class_name AbstractClass
|
@abstract
|
||||||
|
class_name AbstractClass
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
abstract class AbstractSubClass:
|
@abstract class AbstractSubClass:
|
||||||
func _ready():
|
func _ready():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -2132,6 +2204,14 @@ abstract class:
|
|||||||
|
|
||||||
Cannot set object script. Script '<path to script>' should not be abstract.
|
Cannot set object script. Script '<path to script>' should not be abstract.
|
||||||
|
|
||||||
|
Unnamed classes can also be defined as abstract, the ``@abstract`` annotation
|
||||||
|
must precede ``extends``:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
@abstract
|
||||||
|
extends Node
|
||||||
|
|
||||||
Inheritance
|
Inheritance
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ Follow with the optional ``@icon`` then the ``class_name`` if necessary. You can
|
|||||||
GDScript file into a global type in your project using ``class_name``. For more
|
GDScript file into a global type in your project using ``class_name``. For more
|
||||||
information, see :ref:`doc_gdscript_basics_class_name`. If the class is meant
|
information, see :ref:`doc_gdscript_basics_class_name`. If the class is meant
|
||||||
to be an :ref:`abstract class <doc_gdscript_basics_abstract_class>`,
|
to be an :ref:`abstract class <doc_gdscript_basics_abstract_class>`,
|
||||||
add ``abstract`` *before* the ``class_name`` keyword, but on the same line.
|
add ``@abstract`` *before* the ``class_name`` keyword.
|
||||||
|
|
||||||
Then, add the ``extends`` keyword if the class extends a built-in type.
|
Then, add the ``extends`` keyword if the class extends a built-in type.
|
||||||
|
|
||||||
@@ -850,13 +850,25 @@ and how other developers should use it, for example.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
abstract class_name MyNode
|
@abstract
|
||||||
|
class_name MyNode
|
||||||
extends Node
|
extends Node
|
||||||
## A brief description of the class's role and functionality.
|
## A brief description of the class's role and functionality.
|
||||||
##
|
##
|
||||||
## The description of the script, what it can do,
|
## The description of the script, what it can do,
|
||||||
## and any further detail.
|
## and any further detail.
|
||||||
|
|
||||||
|
For inner classes, use single-line declarations:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
## A brief description of the class's role and functionality.
|
||||||
|
##
|
||||||
|
## The description of the script, what it can do,
|
||||||
|
## and any further detail.
|
||||||
|
@abstract class MyNode extends Node:
|
||||||
|
pass
|
||||||
|
|
||||||
Signals and properties
|
Signals and properties
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user