Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
overridesemantics.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2025 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4
/*!
5
\page qtqml-syntax-overridesemantics.html
6
\title Property Shadowing and Override Semantics
7
8
\section1 Property Shadowing
9
10
By default, properties can be \e shadowed: You re-declare a property in a
11
derived QML type, possibly with a new type and new attributes. The result will
12
be two properties of the same name, only one of which is accessible in any given
13
context. This is rarely what you want. Often it's accidental, and most of the time
14
the effects are quite confusing.
15
16
Consider the following example, let's say we have a type Building used in some
17
architectural visualization software written in QML:
18
19
\qml
20
// Building.qml
21
import QtQuick
22
23
Item {
24
property int floors
25
property string rotation // like CSS rotate, "-120deg"
26
property date constructionDate
27
}
28
\endqml
29
30
Building is an Item as it inherits from it but, importantly, the
31
\l {Item::rotation}{rotation property} of \l Item has been shadowed
32
by the newly introduced rotation property on Building.
33
When passing this object to a generic function handling Items, the function will try to
34
read the object's rotation property and expect to get back the property of type real defined by
35
\l Item. Instead, it gets back a string, leading to unexpected results.
36
37
This is also an obstacle for the QML tooling.
38
It can rarely determine the type of a property with certainty without executing the code that
39
manipulates it. This is because the object holding the property can often be of a derived type.
40
41
Therefore this not only confuses the user and leads to unexpected hard-to-spot bugs,
42
but also prevents the tooling from generating more optimized code.
43
44
To address this, the \c final, \c override, and \c virtual keywords — together with
45
additional warnings and errors — were introduced. Their purpose is to help users
46
avoid accidental shadowing and to provide explicit mechanisms for the rare cases
47
when a property truly needs to replace a property from a base type. We refer to
48
such explicit shadowing as \e overriding.
49
50
\note As explained above, shadowing is often accidental and usually leads to ambiguous
51
and hard-to-diagnose behavior. prefer uniquely named properties over both shadowing and overriding
52
whenever possible.
53
54
\section2 Virtual, Override, Final keywords
55
56
\list
57
\li The \c final keyword marks this declaration as final.
58
It may override a property from a base type, but it cannot be overridden or shadowed by derived
59
types. This helps prevent accidental shadowing and allows QML tooling to generate more optimized
60
code.
61
62
\li The \c override keyword indicates that the property intentionally overrides a virtual property
63
from a base type. A property that overrides another does not need to be marked as \c virtual.
64
It automatically inherits the virtuality of the property it overrides. If the original property is
65
virtual, the override is virtual as well. If it isn’t, the override is invalid and will already
66
produce an error.
67
68
\li The \c virtual keyword explicitly indicates that the property is intended to be overriden.
69
Adding \c virtual on the overriding property has no effect, see \c override.
70
\endlist
71
72
This is how they can be used in practice:
73
74
\code
75
// Base.qml
76
QtObject {
77
virtual property int a
78
virtual property int b
79
virtual property var c
80
property var d
81
}
82
83
// DerivedMixed.qml
84
Base {
85
override property var a // fine: overrides property "a" of a Base type
86
final readonly property int b // fine: overrides property "c" of a Base type; can't be overriden any more
87
}
88
89
// DerivedDerivedMixed.qml
90
DerivedMixed {
91
virtual property int a // warning: overrides virtual property, but lacks "override" or "final"
92
override property int a // fine: overrides a property "a" of a DerivedMixed type;
93
final property int a // fine: overrides a property "a" of a DerivedMixed type; can't be overriden any more
94
95
virtual property int b // error: can't override a final property
96
override property int b // error: can't override a final property
97
final property int b // error: can't override a final property
98
99
final property int c // fine: overrides property "c" of a Base type; can't be overriden any more
100
override property int d // error: overrides a property that is not marked virtual
101
}
102
\endcode
103
104
\note Prefer to use \c final over \c override
105
106
Here is also an extensive list of combinations of `virtual`, `override`, and `final` for reference:
107
\code
108
// Base.qml
109
QtObject {
110
property int a // fine: declaring a property
111
virtual property int b // fine: declaring a property that is intended to be overriden
112
final property int c // fine: declaring a property that can't be overriden
113
override property int d // error: does not override anything
114
virtual override property int d // parser error: remove override
115
virtual final property int d // parser error: virtual and final are mutually exclusive
116
}
117
118
// Derived.qml
119
Base {
120
property int a // warning: overrides a property that is not marked virtual
121
property int b // warning: overrides a virtual property, but lacks "override" or "final"
122
property int c // error: can't override a final property
123
}
124
125
// DerivedVirtual.qml
126
Base {
127
virtual property int a // warning: overrides a property that is not marked virtual
128
virtual property int b // warning: overrides a virtual property, but lacks "override" or "final"
129
virtual property int c // error: can't override a final property
130
}
131
132
// DerivedFinal.qml
133
Base {
134
final property int a // warning: overrides a property that is not marked virtual
135
final property int b // fine: overrides a property "b" from the Base type; can't be overriden any more
136
final property int c // error: can't override a final property
137
}
138
139
// DerivedOverride.qml
140
Base {
141
override property int a // error: overrides a property that is not marked virtual
142
override property int b // fine: overrides a property "b" from the Base type
143
override property int c // error: can't override a final property
144
override final property int d // parser error: remove override
145
}
146
\endcode
147
148
\note Most of the warnings will become errors in the future, we can't turn them into errors
149
for now because of the backwards compatibility.
150
151
\note These semantics are enforced by the QmlEngine.
152
153
*/
qtdeclarative
src
qml
doc
src
qmllanguageref
syntax
overridesemantics.qdoc
Generated on
for Qt by
1.16.1