Dart 颤振飞镖构造器

Dart 颤振飞镖构造器,dart,flutter,Dart,Flutter,在颤振示例页面中,有一个名为“向新屏幕发送数据”的项目。我对第65行的建造师有疑问 什么是超级(钥匙:钥匙)?请给我解释一下整行的内容好吗。代码在这里 import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class Todo { final String title; final String description; Todo(this.title, this.de

在颤振示例页面中,有一个名为“向新屏幕发送数据”的项目。我对第65行的建造师有疑问

什么是超级(钥匙:钥匙)?请给我解释一下整行的内容好吗。代码在这里

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}'),
      ),
    );
  }
}
导入“包:flift/foundation.dart”;
进口“包装:颤振/材料.省道”;
待办事项{
最后的字符串标题;
最终字符串描述;
Todo(this.title,this.description);
}
void main(){
runApp(材料应用程序)(
标题:“传递数据”,
主页:TodosScreen(
todos:List.generate(
20,
(i) =>待办事项(
‘Todo$i’,
“关于Todo$i需要做什么的描述”,
),
),
),
));
}
类ToDossScreen扩展了无状态小部件{
最后的待办事项清单;
TodosScreen({Key-Key,@required this.todos}):超级(Key:Key);
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“待办事项”),
),
正文:ListView.builder(
itemCount:todos.length,
itemBuilder:(上下文,索引){
返回列表块(
标题:文本(todos[index].title),
//当用户点击ListTile时,导航到Detail屏幕。
//请注意,我们不仅创建了DetailScreen,而且
//也将当前的todo传递给它!
onTap:(){
导航器。推(
上下文
材料路线(
生成器:(上下文)=>DetailScreen(todo:todos[index]),
),
);
},
);
},
),
);
}
}
类DetailScreen扩展了无状态小部件{
//声明保存Todo的字段
最后的待办事项;
//在构造函数中,需要Todo
DetailScreen({Key Key,@required this.todo}):超级(Key:Key);
@凌驾
小部件构建(构建上下文){
//使用Todo创建我们的UI
返回脚手架(
appBar:appBar(
标题:文本(“${todo.title}”),
),
主体:填充物(
填充:所有边缘设置(16.0),
子项:文本(“${todo.description}”),
),
);
}
}

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

启动“初始值设定项列表”,这是一个逗号分隔的表达式列表,在超类的构造函数之前执行,因此也在构造函数体之前执行。
它通常用于使用断言检查参数值,并用计算值初始化最终字段。
一个限制是,表达式无法读取access
this.
(隐式或显式),因为在执行超级构造函数之前,对象初始化尚未完成

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


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

这是一个需要补充的示例。它是小部件的构造函数

更多说明:

  • 不带
    this.
    前缀的参数是超类的变量
  • 以this开头的参数。是在当前类中定义的变量

通过创建一个与其类同名的函数来声明构造函数(还可以选择添加一个附加标识符,如中所述)。最常见的构造函数形式是生成式构造函数,它创建类的新实例:

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有语法糖分使其变得简单:

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;
  }
}
请记住,构造函数不是继承的,这意味着超类的命名构造函数不是由子类继承的。如果希望使用在超类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数


有关更多信息,请参阅:

可能重复的我不认为这是密钥问题的重复,因为它询问的是整个构造函数,而不仅仅是名为key的参数。
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;
  }
}