diff --git a/tutorials/scripting/gdscript/gdscript_basics.rst b/tutorials/scripting/gdscript/gdscript_basics.rst index eb88b2b36..13d6d4586 100644 --- a/tutorials/scripting/gdscript/gdscript_basics.rst +++ b/tutorials/scripting/gdscript/gdscript_basics.rst @@ -2002,6 +2002,70 @@ in other scripts without the need to ``load`` or ``preload`` them: automatically hidden by the editor windows along with the built-in editor nodes used by the Godot editor. +.. _doc_gdscript_basics_abstract_class: + +Registering abstract classes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since Godot 4.5, you can register abstract classes using the ``abstract`` keyword. +An abstract class is a class that cannot be instantiated directly. Instead, it +is meant to be subclassed by other classes. Attempting to instantiate +an abstract class will result in an error. + +For example, you could have an abstract class called ``Shape`` that defines +a method called ``draw()``. You can then create subclasses like ``Circle`` +and ``Square`` that implement the ``draw()`` method in their own way. +This allows you to define a common *interface* for all shapes without +having to implement all the details in the abstract class itself: + +.. code-block:: gdscript + + abstract class Shape: + 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. + class Circle extends Shape: + func draw(): + print("Drawing a circle.") + + class Square extends Shape: + func draw(): + print("Drawing a square.") + +Both subclasses and classes created using ``class_name`` can be abstract. This +example creates two abstract classes, one of which is a subclass of another +abstract class: + +.. code-block:: gdscript + + abstract class_name AbstractClass + extends Node + + abstract class AbstractSubClass: + func _ready(): + pass + + # This is an example of a concrete subclass of AbstractSubClass. + # This class can be instantiated using `AbstractClass.ConcreteSubclass.new()` + # in other scripts, even though it's part of an abstract `class_name` script. + class ConcreteClass extends AbstractSubClass: + func _ready(): + print("Concrete class ready.") + +.. warning:: + + Since an abstract class cannot be instantiated, it is not possible to attach + an abstract class to a node. If you attempt to do so, the engine will print + an error when running the scene: + + :: + + Cannot set object script. Script '' should not be abstract. + Inheritance ~~~~~~~~~~~ diff --git a/tutorials/scripting/gdscript/gdscript_styleguide.rst b/tutorials/scripting/gdscript/gdscript_styleguide.rst index 1d9df6842..1db7a5cc6 100644 --- a/tutorials/scripting/gdscript/gdscript_styleguide.rst +++ b/tutorials/scripting/gdscript/gdscript_styleguide.rst @@ -801,7 +801,7 @@ We suggest to organize GDScript code this way: 13. remaining static methods 14. overridden built-in virtual methods: 1. _init() - 2. _enter_tree() + 2. _enter_tree() 3. _ready() 4. _process() 5. _physics_process() @@ -813,7 +813,7 @@ We suggest to organize GDScript code this way: And put the class methods and variables in the following order depending on their access modifiers: :: - + 1. public 2. private @@ -829,7 +829,6 @@ This code order follows four rules of thumb: 4. The object's construction and initialization functions, ``_init`` and ``_ready``, come before functions that modify the object at runtime. - Class declaration ~~~~~~~~~~~~~~~~~ @@ -838,7 +837,9 @@ first line of the script. Follow with the optional ``@icon`` then the ``class_name`` if necessary. You can turn a GDScript file into a global type in your project using ``class_name``. For more -information, see :ref:`doc_gdscript_basics_class_name`. +information, see :ref:`doc_gdscript_basics_class_name`. If the class is meant +to be an :ref:`abstract class `, +add ``abstract`` *before* the ``class_name`` keyword, but on the same line. Then, add the ``extends`` keyword if the class extends a built-in type. @@ -849,7 +850,7 @@ and how other developers should use it, for example. :: - class_name MyNode + abstract class_name MyNode extends Node ## A brief description of the class's role and functionality. ## @@ -1066,5 +1067,3 @@ that type will be used to infer the type of the var. This option is considered more :ref:`type-safe` than type hints, but also less null-safe as it silently casts the variable to ``null`` in case of a type mismatch at runtime, without an error/warning. - -