dte*_*ech 5 javascript overriding properties function qml
看起来,尽管QML支持属性和函数的“覆盖”,但这种支持有些笨拙。这是一个示例片段:
// T1.qml
QtObject {
property int p: 1
function f() { return 1 }
}
// T2.qml
T1 {
property string p: "blah"
function f() { return "blah" }
}
// usage
T1 {
Component.onCompleted: {
var obj = this
for (var k in obj) console.log(k + " " + typeof obj[k] + " " + obj[k])
}
}
T2 {
Component.onCompleted: {
var obj = this
for (var k in obj) console.log(k + " " + typeof obj[k] + " " + obj[k])
}
}
Run Code Online (Sandbox Code Playgroud)
覆盖的行为是一致的-不管成员被覆盖了多少次,即使执行以下操作,也总是可以找到正确的成员:
QtObject {
property T1 p : T2 {}
Component.onCompleted: console.log(p.p + " " + p.f())
}
Run Code Online (Sandbox Code Playgroud)
尽管该属性以T1类型声明,但它引用了T2对象,因此输出显示为“ blah blah”。
它也可以基于“实例”工作:
T2 {
function f() { return 1.5 }
Component.onCompleted: {
console.log(f())
}
}
Run Code Online (Sandbox Code Playgroud)
迭代T1的输出符合预期:
qml: objectName string
qml: p number 1
qml: objectNameChanged function function() { [code] }
qml: pChanged function function() { [code] }
qml: f function function() { [code] }
Run Code Online (Sandbox Code Playgroud)
但是,T2的输出有点奇怪:
qml: objectName string
qml: p string blah
qml: p string blah
qml: objectNameChanged function function() { [code] }
qml: pChanged function function() { [code] }
qml: f function function() { [code] }
qml: pChanged function function() { [code] }
qml: f function function() { [code] }
Run Code Online (Sandbox Code Playgroud)
它两次列出了“重写的”成员,但是,似乎其中一个不是来自“基础”类型,另一个似乎不是来自“派生”成员-因为两者p
都是字符串。
var obj = this
for (var k in obj) if ((k === "f") && (typeof obj[k] === "function")) console.log(obj[k]())
Run Code Online (Sandbox Code Playgroud)
f
两次调用这两个函数都会输出“ blah”-因此,对“ override”函数也是如此。
我希望迭代“派生”对象将显示两次属性和功能,但是其中之一将来自基类型。让它们实际上重复,两者都指向同一个成员似乎毫无意义且不合逻辑。在实例级别进行覆盖将放置另一个成员,并且所有三个成员再次引用最新的覆盖。因此,从技术上讲,甚至无法手动选择替代。
所以我的问题是是否可以指定替代:
// in T2.qml - pseudocode
property string p: T1::p + "blah" // value is "1 blah"
f() { return T1:: f() + "blah" } // returning "1 blah"
Run Code Online (Sandbox Code Playgroud)
尝试以幼稚的方式进行操作会导致重大失败:
// in T2.qml
property string p: p + "blah" // binding loop, p does not refer to T1's p
f() { return f() + "blah" } // stack overflow, f does not refer to T1's f
Run Code Online (Sandbox Code Playgroud)
找到了一种简单而幼稚的手动解决方案:
// T1.qml
QtObject {
function f() { return f_t1() }
function f_t1() { return 1 }
}
// T2.qml
T1 {
function f() { return f_t2() }
function f_t2() { return f_t1() + " blah " }
}
// usage
T2 {
function f() { return f_t2() + 1.5}
Component.onCompleted: console.log(f()) // outputs 1 blah 1.5
}
Run Code Online (Sandbox Code Playgroud)
简而言之,为重写的每个级别的“继承”显式命名函数,并使用未修饰的函数重写进行多态访问,因此现在“基”类型实现可以由派生类重用。