提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
函数
可选的位置参数
要指定可选的位置参数,请使用方括号 [ ] 。
void function_name(param1,[optional_param1,optional_param2]){ }
如果未传递可选参数,则将其设为null。
viod main(){
test(123);
}
// 可选参数添加可空标识符
test(int n,[String? m]){
print(n); // 123
print(m); // null
}
可选的命名参数
与位置参数不同,必须在传递值时指定参数的名称,花括号 { } 可用于指定可选的命名参数。
void function_name(a,{optional_param1,optional_param2}){ }
示例
void main(){
test(123,s1:'hello');
test(123,s2:'hello',s1:'world')
}
// 可选的命名参数要不给予一个默认值,要不添加关键字required表示该命名参数必须要赋值
test(int n,{required String s1,String s2='world'}){
print(n);
print(s1);
print(s2);
}
带有默认值的可选参数
默认情况下,还可以为函数参数指定值,但是,这些参数也可以显式传递值。
function_name(param1,{param2 : defalut_value}){ }
示例
void main(){
test(123);
}
void test(n,{s1:12}){
print(n);
print(s1);
}
注:函数中所有必须参数必须要写在可选参数之前。
匿名函数
创建没有名字的函数。这种函数被称为匿名函数。
([[Type] param1[, ...]]) { codeBlock;};
示例
void main() {
var list = ['apple', 'bananas', 'oranges'];
list.forEach((item){
print('${list.indexOf(item)}: $item');
});
}
如果函数只有一条语句,可以使用箭头简写。
list.forEach((item) => print('${list.indexOf(item)}: $item'));
Lambda函数
Lambda函数是表示函数的简洁机制,这些函数可以使用箭头简写。
void main(){
printMsg();
print(test());
}
printMsg() => print('hello');
int test() => 123;
内嵌函数
在Dart中,支持函数的嵌套,嵌套函数可以访问上一层的函数变量。例如在该示例中,内嵌函数push()可以访问夫函数的count变量:
int add(){
var count = 0;
int plus() {
count += 1;
}
plus();
return count;
}
main(){
print(add());
print(add());
print(add());
}
自执行函数
在Dart中,可以定义一个没有函数名的并且在定义完成后自己执行一次。
mian(){
(x,y) {
print('$x,$y');
}(3,5);
}
闭包
闭包是一种保护私有变量的机制,在函数执行是形成私有的作用域,保护里面的私有变量不受外界干扰,直观的说就是形成一个不销毁的栈环境。
类
声明方式
class class_name {
<Fields>
<getters/setters>
<constructors>
<functions>
}
示例
class Car {
// field
String engine = 'EA888';
// function
void disp() {
print(engine);
}
}
构造函数
默认构造函数,在实例化时,自动得调用
class Point {
num x, y;
// 默认构造函数
Point() {
print('这是默认的构造函数,实例化时,会被第一个调用。');
}
}
class Car {
// late String engine;
String? engine;
Car(String engine){
this.engine = engine;
print('This engine is : ${engine}');
}
}
class Book {
String name;
String autor;
Book(this.name,this.autor);
}
void main() {
Point p = Point();
Car car = Car('EA888');
Book b = Book('西游记','吴承恩');
print(p.x);
print('${b.name}, ${b.autor}');
// The engine is EA888
// 这是默认的构造函数,实例化时,会被第一个调用。
// null
// 西游记,吴承恩
}
命名构造函数
在类中可以使用命名构造函数 (类名.函数名)实现多个构造器。
class_name.constructor_name(param_list);
示例
void main() {
Car c1 = Car.namedConst('EA888');
Car c2 = Car();
// 在dart中,例如DateTime
DateTime d = DateTime.now();
}
class Car {
String wheels;
Car() {
print('Non-parameterized constructor invoked');
}
Car.namedConst(String engine) {
print('The engine is : ${engine}');
}
Car.namedConst2(this.wheels);
}
常量构造函数
如果类生成的对象不会改变,可以通过常量构造函数使这些对象成为编译时常量
class Book {
// 属性必须通过 final 声明
final String name;
final String author;
// 常量构造函数,必须通过const声明
const Book(this.name,this.author);
}
viod main() {
// 通过常量构造函数创建参数相同的对象时,内存中只保留一份
// 声明不可变对象,必须通过const关键字
var b1 = const Book('西游记','吴承恩');
var b2 = const Book('西游记','吴承恩');
print(b1 == b2); // true
// 常量构造函数,可以当作普通构造函数使用
var b3 = new Book('西游记','吴承恩');
var b4 = new Book('西游记','吴承恩');
print(b3 == b4); // false
// 实例化时,new关键词可以省略
var b5 = Book('西游记','吴承恩');
var b6 = Book('西游记','吴承恩');
print(b5 == b6); // false
}
identical
检查两个引用是否指向同一个对象
class Book {
// 属性必须通过 final 声明
final String name;
final String autor;
// 常量构造函数,必须通过const声明
const Book(this.name,this.author);
}
// 声明不可变对象,必须通过const关键字
var b1 = const Book('西游记','吴承恩');
var b2 = const Book('西游记','吴承恩');
print(b1 == b2); // true
print(identical(c1,c2)); // true
// 常量构造函数,可以当作普通构造函数使用
var b3 = Book('西游记','吴承恩');
var b4 = Book('西游记','吴承恩');
print(b3 == b4); // false
print(identical(c3,c4)); // false
工厂构造函数
通过factory声明,工厂函数不会自动生成实例,而实通过代码来决定返回的实例
class Car {
int wheels;
static Car? instance;
// 命名构造函数
Car.newCar(this.wheels){
print('我执行了一次');
}
// 工厂构造函数 -- 接受一个可选参数并赋默认值4
factory Car([int wheels = 4]) {
// 工厂构造函数中,不能使用this关键字
// print(this.wheels);
// 如果instance为空,则实例化并把值赋给instance
// ??= 赋值运算符表示的是左边的值是否为空,如果为空,则把右边的值赋给左边
return instance ??= Car.newCar(wheels);
}
}
void main() {
Car c1 = Car(6);
Car c2 = Car();
print(c1.wheels); // 6
print(c2.wheels); // 6
print(c1 == c2); // true
}
Getter,Setter
默认的getter/setter与每个类相关联。但是,可以通过显式定义getter/setter来覆盖默认值。getter没有参数并返回一个值,setter只有一个参数但不返回值。
class Student {
String name;
int age;
get studentName {
return name;
}
set studentName(String name) {
this.name = name;
}
get studentAge {
return age;
}
set studentAge(int age) {
this.age = age;
}
}
void main() {
Student s = new Student();
s.studentName = '张三';
print('${s.studentName}');
s.studentAge = 18;
print('${s.studentAge}');
}
访问修饰符
Dart没有访问修饰符,在Dart类中,默认的访问修饰符是公开的,如果要使用私用属性,需要同时满足以下两个条件:
- 属性或方法以 _(下划线)开头
- 只有把类单独抽离出来,私有属性和方法才起作用,因为同一个文件下不存在私用的情况
class Person {
String name;
// 声明私有属性
num _age = 8;
Person(this.name);
num getAge() {
return this._age;
}
}
import 'lib/Person.dart';
void main() {
Person p = new Person('jeck');
print(p.name);
print(p.getAge());
}
抽象类
在Dart中,没有接口,只有抽象类使用abstract class表示。通过使用关键字implements可以多实现,通过使用关键字extends可以继承,只能单继承。
abstract class A {
late String name;
printA();
}
abstract class B {
printB();
}
class C implements A,B {
late String name;
printA() {
print('A');
}
printB() {
print('B');
}
}
mixins
在Dart中本不可以实现多继承,利用mixins可实现类似多继承的功能。
- 作为mixins的类只能继承自Object,不能继承其他类。
- 作为mixins的类不能有构造函数。
- 一个类可以mixins多个mixins类。
- mixins绝不是继承,也不是接口,而是一种全新的特性。
class A {
String info = 'this is A';
void printA() {
print('A');
}
}
class B {
void printB() {
print('B');
}
}
class Person {
String name;
num age;
Person(this.name,this.age);
void printInfo() {
print('name is ${this.name}, age is ${this.age}');
}
}
//使用with关键字实现mixins
class C with A,B {}
// 即继承自Person有mixins A和B,with后跟的类有顺序之分,后类的方法会覆盖前类的方法
class D extends Person with A,B {}
void main() {
var c = new C();
c.printA(); // A
c.printB(); // B
print(c.info); // This is A
}
mixins的类型就是其超类的子类型。
class A {
String info = 'this is A';
void printA() {
print('A');
}
}
class B {
String info = 'this is B';
void printB() {
print('B');
}
}
class C with A,B {}
void main() {
var c = C();
// 如果混入的类中存在相同属性和方法,后面的类会把覆盖前面的类的属性和方法
print(c.info); // this is B
print(c is C); // true
print(c is A); // true
print(c is B); // true
}
extends,implements,with可以同时使用,但是有前后顺序:extends - with- implements。
class A extends B with C, D implements E, F {}