我想在 Dart 中執行此操作:
abstract class A
{
int f();
}
class A1 extends A
{
@override
int f() => 1515;
}
class A2 extends A
{
@override
int f() => 1789;
}
class X<T extends A> extends T
{
int x() => f();
}
void main()
{
X<A1> x1 = X<A1>();
X<A2> x2 = X<A2>();
print( x1.x() ); // Should print 1515;
print( x2.x() ); // Should print 1789;
}
關鍵行是定義模板類 X 的行:編譯器抱怨因為 X 繼承了模板引數(它擴展了 A,所以它可以知道它是一個類)。
我可能承認我將語言推得有點遠(我的 C 背景......)但是有沒有辦法在 Dart 中執行此操作?
附錄
我試過這個:
abstract class A
{
A();
int f();
}
class A1 extends A
{
A1();
@override
int f() => 1515;
}
class A2 extends A
{
A2();
@override
int f()=>1789;
}
class X<T extends A> {
late T t;
X(){
t = T();
}
int x() => t.f();
}
void main()
{
X<A1> x1 = X<A1>();
X<A2> x2 = X<A2>();
print( x1.x() );
print( x2.x() );
}
但是編譯器現在抱怨t = T(); ...
'T' 不是函式。嘗試更正名稱以匹配現有函式,或定義方法或函式名稱“T”。
uj5u.com熱心網友回復:
Dart 有泛型,與 C 模板相似但又不同。C 模板更類似于在編譯時替換模板引數的宏,它會為模板引數的每個組合生成模板類的單獨編譯版本。Dart 泛型是不同的,而是類似于Java 的:泛型類只有一個編譯版本。
因此,您不能像使用 C 那樣使用鴨子型別,T也不能呼叫T建構式或static方法。
相反,您可以做的是提供一個構造 a 的回呼T,例如:
class X<T extends A> {
T t;
X(T Function() makeT) : t = makeT();
int x() => t.f();
}
void main()
{
X<A1> x1 = X(A1.new);
X<A2> x2 = X(A2.new);
...
}
(我也X.t不再late(late如果您通過建構式的初始化串列對其進行初始化,則不需要)并在呼叫X建構式時洗掉了顯式型別引數(它們現在可以從引數中推斷出來)。)
uj5u.com熱心網友回復:
即使沒有模板,這也是一個解決方案,但概念與我正在尋找的不匹配。
- 在上面的問題中,X 和 x 本身就是兩種不同的服務。
- 在下面的解決方案中,X 是使用 A1 或 A2 作為子服務提供者的服務。
瞧:
abstract class A
{
A();
int f();
}
class A1 extends A
{
A1();
@override
int f() => 1515;
}
class A2 extends A
{
A2();
@override
int f()=>1789;
}
class X {
late A t;
X(A x){
t = x;
}
int x() => t.f();
}
void main()
{
X x1 = X(A1());
X x2 = X(A2());
print( x1.x() ); // Indeed prints 1515
print( x2.x() ); // Indeed prints 1789
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/448956.html
