프로퍼티 섀도잉 및 오버라이드 시맨틱
프로퍼티 섀도잉
기본적으로 프로퍼티는 섀도잉할 수 있습니다: 새 유형과 새 속성을 사용하여 파생된 QML 유형으로 프로퍼티를 다시 선언하면 됩니다. 그 결과 같은 이름의 프로퍼티 두 개가 생성되며, 이 중 하나만 특정 컨텍스트에서 액세스할 수 있습니다. 이는 원하는 경우가 거의 없습니다. 종종 우발적으로 발생하며 대부분의 경우 그 효과가 상당히 혼란스럽습니다.
다음 예를 들어 QML로 작성된 일부 건축 시각화 소프트웨어에서 Building 유형이 사용된다고 가정해 보겠습니다:
// Building.qml import QtQuick Item { property int floors property string rotation // like CSS rotate, "-120deg" property date constructionDate }
Building은 이를 상속하는 항목이지만, 중요한 것은 Item 의 rotation property 이 Building에 새로 도입된 회전 속성에 의해 그림자가 생겼다는 점입니다. 이 객체를 Items를 처리하는 일반 함수에 전달하면 이 함수는 객체의 회전 속성을 읽으려고 시도하고 Item 에 정의된 실제 유형의 속성을 반환할 것으로 예상합니다. 대신 문자열을 반환하여 예기치 않은 결과를 초래합니다.
이는 QML 툴링의 장애물이기도 합니다. 프로퍼티를 조작하는 코드를 실행하지 않고서는 프로퍼티의 유형을 확실하게 파악할 수 있는 경우는 거의 없습니다. 프로퍼티를 보유한 객체가 파생된 유형일 수 있기 때문입니다.
따라서 사용자에게 혼란을 주고 예기치 않게 발견하기 어려운 버그가 발생할 뿐만 아니라 툴링이 보다 최적화된 코드를 생성하지 못하게 됩니다.
이 문제를 해결하기 위해 final, override, virtual 키워드가 추가 경고 및 오류와 함께 도입되었습니다. 이 키워드의 목적은 사용자가 실수로 섀도잉을 방지하고 프로퍼티가 기본 유형에서 프로퍼티를 대체해야 하는 드문 경우에 대비해 명시적인 메커니즘을 제공하는 것입니다. 이러한 명시적 섀도잉을 오버라이딩이라고 합니다.
참고: 위에서 설명한 것처럼 섀도잉은 종종 우발적으로 발생하며 대개 모호하고 진단하기 어려운 동작으로 이어집니다. 가능하면 섀도잉과 오버라이딩 모두보다 고유한 이름의 프로퍼티를 선호하세요.
가상, 오버라이드, 최종 키워드
final키워드는 이 선언을 최종 선언으로 표시합니다. 기본 유형에서 프로퍼티를 재정의할 수는 있지만 파생 유형에 의해 재정의되거나 섀도잉될 수는 없습니다. 이렇게 하면 우발적인 섀도잉을 방지하고 QML 도구가 보다 최적화된 코드를 생성할 수 있습니다.override키워드는 프로퍼티가 기본 유형에서 가상 프로퍼티를 의도적으로 재정의한다는 것을 나타냅니다. 다른 프로퍼티를 재정의하는 프로퍼티는virtual로 표시할 필요가 없습니다. 재정의하는 프로퍼티의 가상성을 자동으로 상속합니다. 원래 프로퍼티가 가상인 경우 오버라이드도 가상입니다. 그렇지 않은 경우 재정의는 유효하지 않으며 이미 오류가 발생합니다.virtual키워드는 해당 프로퍼티가 재정의될 것임을 명시적으로 나타냅니다. 재정의 속성에virtual을 추가해도 아무런 효과가 없습니다(override참조).
이것이 실제 사용 방법입니다:
// 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 }
참고: final 보다 override
다음은 `virtual`, `override` 및 `final`의 조합에 대한 광범위한 목록도 참조할 수 있습니다:
// 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 }
참고: 대부분의 경고는 향후에 오류가 될 예정이며, 현재로서는 이전 버전과의 호환성 때문에 오류로 전환할 수 없습니다.
참고: 이러한 의미는 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.