Flutter Dart构造函数

时间:2018-06-24 19:48:16

标签: dart flutter

在“示例波动”页面中,有一个名为“将数据发送到新屏幕”的项目。我有疑问要在第65行保留构造函数。

Sending Data to a new screen

  // In the constructor, require a Todo
  DetailScreen({Key key, @required this.todo}) : super(key: key);

什么是超级(键:键)?请给我整个行的解释。代码在这里。...

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Todo {
  final String title;
  final String description;

  Todo(this.title, this.description);
}

void main() {
  runApp(MaterialApp(
    title: 'Passing Data',
    home: TodosScreen(
      todos: List.generate(
        20,
            (i) => Todo(
          'Todo $i',
          'A description of what needs to be done for Todo $i',
        ),
      ),
    ),
  ));
}

class TodosScreen extends StatelessWidget {
  final List<Todo> todos;

  TodosScreen({Key key, @required this.todos}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Todos'),
      ),
      body: ListView.builder(
        itemCount: todos.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(todos[index].title),
            // When a user taps on the ListTile, navigate to the DetailScreen.
            // Notice that we're not only creating a DetailScreen, we're
            // also passing the current todo through to it!
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailScreen(todo: todos[index]),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  // Declare a field that holds the Todo
  final Todo todo;

  // In the constructor, require a Todo
  DetailScreen({Key key, @required this.todo}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Use the Todo to create our UI
    return Scaffold(
      appBar: AppBar(
        title: Text("${todo.title}"),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text('${todo.description}'),
      ),
    );
  }
}

3 个答案:

答案 0 :(得分:10)

构造函数有两个命名参数。
默认情况下,命名参数是可选的。
@required是Dart分析器识别的注释,如果在构建时调用时未通过,则会产生警告(在运行时无效)。

:开始“初始化列表”,这是在超类的构造函数之前执行的表达式的逗号分隔列表,因此也在构造函数主体之前执行。
它通常用于使用断言检查参数值,以及使用计算值初始化最终字段。
局限性在于,表达式无法读({隐式或显式地)访问this.,因为在执行超级构造函数之前对象初始化未完成。

初始化器中的最后一个元素是对父类的默认构造函数的隐式调用(如果省略),或者对当前类或父类的特定构造函数的调用(如果给定的话)。

在您的问题示例中,传递给构造函数的key参数被转发到超类未命名构造函数的命名参数key

答案 1 :(得分:8)

这是对GünterZöchbauer的解释的补充示例。它是Align小部件的构造函数。

class Align extends SingleChildRenderObjectWidget {

  // constructor
  const Align({
    Key key,                                                   // named parameter
    this.alignment = Alignment.center,                         // named parameter
    this.widthFactor,                                          // named parameter
    this.heightFactor,                                         // named parameter
    Widget child                                               // named parameter
  }) : assert(alignment != null),                              // initializer list
       assert(widthFactor == null || widthFactor >= 0.0),      // initializer list
       assert(heightFactor == null || heightFactor >= 0.0),    // initializer list
       super(key: key, child: child);                          // initializer list

  // class variables
  final AlignmentGeometry alignment;
  final double widthFactor;
  final double heightFactor;

更多说明:

  • 没有this.前缀的参数是超类的变量。
  • this.开头的参数是当前类中定义的变量。

答案 2 :(得分:3)

通过创建一个与其类同名的函数来声明一个构造函数(加上可选的附加标识符,如Named constructors中所述)。最常见的构造器形式,生成式构造器,用于创建一个类的新实例:

class Point {
  double x, y;

  Point(double x, double y) {
    // There's a better way to do this, stay tuned.
    this.x = x;
    this.y = y;
  }
}

this 关键字指的是当前实例。

注意:仅当存在名称冲突时才使用此选项。否则,Dart 样式会忽略 this。

将构造函数参数分配给实例变量的模式非常常见,Dart 有语法糖来简化:

class Point {
  double x, y;

  // Syntactic sugar for setting x and y
  // before the constructor body runs.
  Point(this.x, this.y);
}

默认构造函数

如果您不声明构造函数,则会为您提供默认构造函数。默认构造函数没有参数并调用超类中的无参数构造函数。

构造函数不被继承

子类不从其超类继承构造函数。未声明构造函数的子类只有默认(无参数,无名称)构造函数。

命名构造函数

使用命名构造函数为一个类实现多个构造函数或提供额外的清晰度:

class Point {
  double x, y;

  Point(this.x, this.y);

  // Named constructor
  Point.origin() {
    x = 0;
    y = 0;
  }
}

记住构造函数不是继承的,这意味着超类的命名构造函数不会被子类继承。如果您希望使用在超类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数。

有关更多信息,请参阅:https://dart.dev/guides/language/language-tour#constructors