簡體   English   中英

Dart / Flutter 子類化以使用可選參數

[英]Dart / Flutter subclassing to use optional parameters

我試圖弄清楚如何在不指定父類的所有可選參數的情況下創建類的子類,但仍然可以從子類的構造函數訪問它們。 在繼承具有無數屬性的 Flutter 小部件時,這一點尤其重要。

例如,DoorWidget 是具有許多可選參數的父類。

ChildDoorWidget 繼承了 DoorWidget 來增加額外的邏輯,但仍然想要所有可選的父參數,而不必在子類的 super() 方法中指定每個參數。

有沒有辦法做到這一點?

這是一個例子。

    // Maine widget
    class DoorWidget {
      String color = 'red';
      int width;
      int height;
      int p1;
      int p2;
      int p3;
      Function onKicked = () => print('Kicked');

      DoorWidget(this.color, {this.onKicked, this.width, this.height, this.p1, this.p2, this.p3});
    }

    class ChildDoorWidget extends DoorWidget {
      @override
      String color = 'green';
      ChildDoorWidget(String color, {Function onKicked, int width, int height})
          // Do I need to specify every parent optional parameter in the super class?
          // Is there a way to avoid this.
          : color = color,
            super(color, onKicked: onKicked, width: width);
    }

    main() {

      DoorWidget d = DoorWidget('green', width: 10, onKicked: () => print('DoorWidget Kicked') );
      print('Text Class');
      print(d.color);
      print(d.width);
      d.onKicked();

      ChildDoorWidget c = ChildDoorWidget('blue',
          width: 12, onKicked: () => print('ChildDoorWidget tapped called'));
      // Ideally I would like to do this:
      //  ChildDoorWidget m = ChildDoorWidget('blue', width: 12, onKicked: () => print('tapped called'), p1: 1, p2: 2, and any other optional params);
      print('\nMyText Class');
      print(c.color);
      print(c.width);
      c.onKicked();
    }

實際上,沒有直接和簡單的方法來調用帶有未定義參數的構造函數。

你想打電話給:

ChildDoorWidget m = ChildDoorWidget('blue', width: 12, 
                      onKicked: () => print('tapped called'),
                      p1: 1, p2: 2);

但是由於p1p2未在 ChildDoorWidget 的構造函數上定義,您會收到錯誤“未定義命名參數”。 .

解決方法是記住p1p2可以被ChildDoorWidget訪問,並且使用級聯表示法您仍然可以在調用構造函數的同一語句上設置它們的值:

ChildDoorWidget m = ChildDoorWidget('blue', width: 12, 
                      onKicked: () => print('tapped called'))
                      ..p1=1..p2=2;

除了必需的參數(本例中的color )之外,您可以對所有參數執行相同的操作

ChildDoorWidget m = ChildDoorWidget('blue')
                   ..width = 12
                   ..onKicked = (() => print('tapped called'))
                   ..p1 = 1
                   ..p2 = 2;

請記住,在執行級聯賦值之前,構造函數的代碼已完全執行。 因此,僅對不使用其參數執行立即操作的構造函數使用此解決方法,例如在您的示例中。

同樣的邏輯可以應用於您關於在超類中指定父級可選參數的問題。

觀察:初始化值coloronKickedDoorWidget因為構造覆蓋這些值是沒用的。 這對 ChildDoorWidget 上的color有效。

以下是對上述實現的初始代碼的修訂:

void show(dynamic d) {
  print('\ncolor=${d.color}\nwidth=${d.width}\nheight=${d.height}\np1=${d.p1}\np2=${d.p2}\np3=${d.p3}\nonKicked=${d.onKicked}');
  d.onKicked == null ? '' : d.onKicked();
}

class DoorWidget {
  String color;
  int width;
  int height;
  int p1;
  int p2;
  int p3;
  Function onKicked;
  DoorWidget(this.color,
      {this.onKicked, this.width, this.height, this.p1, this.p2, this.p3});
}

class ChildDoorWidget extends DoorWidget {
  @override
  String color = 'orange'; //initialization useless because constructor overrides it with "this.color"

  ChildDoorWidget(String this.color) : super(color);
}

main() {
  print('\n\n\n create DoorWidget with color, width and onKicked');
  DoorWidget d = DoorWidget('green',
      width: 10, onKicked: () => print('DoorWidget Kicked'));
  show(d);

  print('\n\n\n create ChildDoorWidget with color, width and onKicked');
  ChildDoorWidget c = ChildDoorWidget('blue')
    ..width = 12
    ..onKicked = () => print('ChildDoorWidget tapped called');
  show(c);

  print('\n\n\n create ChildDoorWidget with many parameters');
  ChildDoorWidget m = ChildDoorWidget('yellow')
    ..width = 12
    ..onKicked = (() => print('tapped called'))
    ..p1 = 1
    ..p2 = 2;
  show(m);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM