이 페이지에서

프로퍼티 섀도잉 및 오버라이드 시맨틱

프로퍼티 섀도잉

기본적으로 프로퍼티는 섀도잉할 수 있습니다: 새 유형과 새 속성을 사용하여 파생된 QML 유형으로 프로퍼티를 다시 선언하면 됩니다. 그 결과 같은 이름의 프로퍼티 두 개가 생성되며, 이 중 하나만 특정 컨텍스트에서 액세스할 수 있습니다. 이는 원하는 경우가 거의 없습니다. 종종 우발적으로 발생하며 대부분의 경우 그 효과가 상당히 혼란스럽습니다.

다음 예를 들어 QML로 작성된 일부 건축 시각화 소프트웨어에서 Building 유형이 사용된다고 가정해 보겠습니다:

// Building.qml
import QtQuick

Item {
    property int floors
    property string rotation // like CSS rotate, "-120deg"
    property date constructionDate
}

Building은 이를 상속하는 항목이지만, 중요한 것은 Itemrotation 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.