Sémantique de l'ombre des propriétés et de l'écrasement
L'ombre des propriétés
Par défaut, les propriétés peuvent être masquées: Vous redéclarez une propriété dans un type QML dérivé, éventuellement avec un nouveau type et de nouveaux attributs. Il en résulte deux propriétés portant le même nom, dont une seule est accessible dans un contexte donné. C'est rarement ce que vous souhaitez. C'est souvent accidentel, et la plupart du temps, les effets sont assez déroutants.
Prenons l'exemple suivant : disons que nous avons un type Bâtiment utilisé dans un logiciel de visualisation architecturale écrit en QML :
// Building.qml import QtQuick Item { property int floors property string rotation // like CSS rotate, "-120deg" property date constructionDate }
Building est un Item puisqu'il en hérite mais, surtout, la propriété rotation property de Item a été éclipsée par la propriété de rotation nouvellement introduite sur Building. Lorsqu'elle transmet cet objet à une fonction générique gérant les éléments, la fonction tente de lire la propriété de rotation de l'objet et s'attend à obtenir en retour la propriété de type real définie par Item. Au lieu de cela, elle obtient une chaîne de caractères, ce qui conduit à des résultats inattendus.
Il s'agit également d'un obstacle pour l'outil QML. Il est rarement possible de déterminer avec certitude le type d'une propriété sans exécuter le code qui la manipule. En effet, l'objet qui détient la propriété peut souvent être d'un type dérivé.
Par conséquent, non seulement cela perturbe l'utilisateur et conduit à des bogues inattendus et difficiles à détecter, mais cela empêche également l'outil de générer un code plus optimisé.
Pour remédier à ce problème, les mots-clés final, override, et virtual - ainsi que des avertissements et des erreurs supplémentaires - ont été introduits. Leur but est d'aider les utilisateurs à éviter l'ombrage accidentel et de fournir des mécanismes explicites pour les rares cas où une propriété doit vraiment remplacer une propriété d'un type de base. Nous appelons cette filiation explicite " surcharge".
Note : Comme expliqué ci-dessus, le shadowing est souvent accidentel et conduit généralement à un comportement ambigu et difficile à diagnostiquer. Dans la mesure du possible, préférez les propriétés à nom unique au shadowing et au overriding.
Mots-clés Virtual, Override, Final
- Le mot-clé
finalindique que cette déclaration est finale. Elle peut remplacer une propriété d'un type de base, mais elle ne peut pas être remplacée ou remplacée par des types dérivés. Cela permet d'éviter les ombres accidentelles et permet à l'outil QML de générer un code plus optimisé. - Le mot-clé
overrideindique que la propriété remplace intentionnellement une propriété virtuelle d'un type de base. Une propriété qui en remplace une autre n'a pas besoin d'être marquée commevirtual. Elle hérite automatiquement de la virtualité de la propriété qu'elle remplace. Si la propriété d'origine est virtuelle, la surcharge l'est également. Si ce n'est pas le cas, la surcharge n'est pas valide et produira déjà une erreur. - Le mot-clé
virtualindique explicitement que la propriété est destinée à être remplacée. L'ajout devirtualsur la propriété à remplacer n'a aucun effet, voiroverride.
Voici comment ils peuvent être utilisés dans la pratique :
// Base.qml QtObject { virtual property int a virtual property int b virtual property var c property var d } // DerivedMixed.qml Base { override property var a // fine: overrides property "a" of a Base type final readonly property int b // fine: overrides property "c" of a Base type; can't be overriden any more } // DerivedDerivedMixed.qml DerivedMixed { virtual property int a // warning: overrides virtual property, but lacks "override" or "final" override property int a // fine: overrides a property "a" of a DerivedMixed type; final property int a // fine: overrides a property "a" of a DerivedMixed type; can't be overriden any more virtual property int b // error: can't override a final property override property int b // error: can't override a final property final property int b // error: can't override a final property final property int c // fine: overrides property "c" of a Base type; can't be overriden any more override property int d // error: overrides a property that is not marked virtual }
Note : Il est préférable d'utiliser final plutôt que override
Voici également une liste étendue de combinaisons de `virtual`, `override`, et `final` pour référence :
// Base.qml QtObject { property int a // fine: declaring a property virtual property int b // fine: declaring a property that is intended to be overriden final property int c // fine: declaring a property that can't be overriden override property int d // error: does not override anything virtual override property int d // parser error: remove override virtual final property int d // parser error: virtual and final are mutually exclusive } // Derived.qml Base { property int a // warning: overrides a property that is not marked virtual property int b // warning: overrides a virtual property, but lacks "override" or "final" property int c // error: can't override a final property } // DerivedVirtual.qml Base { virtual property int a // warning: overrides a property that is not marked virtual virtual property int b // warning: overrides a virtual property, but lacks "override" or "final" virtual property int c // error: can't override a final property } // DerivedFinal.qml Base { final property int a // warning: overrides a property that is not marked virtual final property int b // fine: overrides a property "b" from the Base type; can't be overriden any more final property int c // error: can't override a final property } // DerivedOverride.qml Base { override property int a // error: overrides a property that is not marked virtual override property int b // fine: overrides a property "b" from the Base type override property int c // error: can't override a final property override final property int d // parser error: remove override }
Note : La plupart des avertissements deviendront des erreurs dans le futur, nous ne pouvons pas les transformer en erreurs pour le moment à cause de la compatibilité ascendante.
Note : Cette sémantique est appliquée par le QmlEngine.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.