Flutter入门篇(三):dart语言(2)

参考:https://zhuanlan.zhihu.com/p/83387088


一.运算

1.??--------------判断前面是否是null,如果是就执行??后面的内容

//??
var num temp = exp1 ?? exp2//如果temp是null那么exp2赋值给temp

//??= 
var num temp ??= exp1//如果temp是null那么exp1赋值给temp,否则temp不变

2.~/取模

3.  .. --------------级联语法,对对象的连续操作

class Person {
  String name;

  void run() {
    print("${name} is running");
  }

  void eat() {
    print("${name} is eating");
  }

  void swim() {
    print("${name} is swimming");
  }
}

main(List<String> args) {
  final p1 = Person();
  p1.name = 'why';
  p1.run();
  p1.eat();
  p1.swim();

  final p2 = Person()
              ..name = "why"
              ..run()
              ..eat()
              ..swim();
}

 其他运算和C语言一样


二. 流程控制

var names = ['why', 'kobe', 'curry'];
for (var name in names) {//这个和python有点像只不过多了个()
  print(name);
}

其他和C语言一样


三.类和对象

 定义和python一样

class 类名 {
  类型 成员名;
  返回值类型 方法名(参数列表) {
    方法体
  }
}

 1.set 和 get

默认情况下,类定义的属性是可以直接被外界访问的

但是为了保证数据的安全性可以使用set和get对成员进行修改访问

main(List<String> args) {
  final d = Dog("黄色");
  d.setColor = "黑色";
  print(d.getColor);
}

class Dog {
  String color;

  String get getColor {//get
    return color;
  }
  set setColor(String color) {//set函数类型为null
    this.color = color;
  }

  Dog(this.color);
}

2. 继承--------------extends

父类中的所有成员变量和方法都会被继承,,但是构造方法除外。

class Animal {
  int age;

  run() {
    print('在奔跑ing');
  }
}

class Person extends Animal {

}

子类的构造方法在执行前,将隐含调用父类的无参默认构造方法。如果父类没有无参默认构造方法(即父类有一个带参数的构造方法),那么子类的构造方法里必须通过super调用父类的构造方法

class Animal {
  int age;

  Animal(this.age);

  run() {
    print('在奔跑ing');
  }
}

class Person extends Animal {
  String name;
  //:表示冒号后面的内容在前面的函数执行后会自动执行
  Person(String name, int age) : name=name, super(age);

  @override //override 是重载
  run() {
    print('$name在奔跑ing');
  }

  @override
  String toString() {
    return 'name=$name, age=$age';
  }
}

 3.抽象类-------------abstract

抽线类里面只能声明函数不能定义,抽象类不能实例化

抽象类里的方法叫做抽象方法必须被子类实现

abstract class Shape {
  getArea();
}

class Circle extends Shape {
  double r;

  Circle(this.r);

  @override
  getArea() {
    return r * r * 3.14;
  }
}

class Reactangle extends Shape {
  double w;
  double h;

  Reactangle(this.w, this.h);

  @override
  getArea() {
    return w * h;
  }
}

 4.隐式接口---------------implements

默认情况下,定义的每个类都相当于默认也声明了一个接口,可以由其他的类来实现

在通过implements实现某个类时,类中所有的方法都必须被重新实现(无论这个类原来是否已经实现过该方法)

abstract class Runner {
  run();
}

abstract class Flyer {
  fly();
}

class SuperMan implements Runner, Flyer {
  @override
  run() {
    print('超人在奔跑');
  }

  @override
  fly() {
    print('超人在飞');
  }
}

 5.Mixin混入-------------------with

mixin定义的类可以被其他类混入使用(mixin里的方法可以不被重载),使用with来进行混入

main(List<String> args) {
  var superMan = SuperMain();
  superMan.run();
  superMan.fly();
}

mixin Runner {
  run() {
    print('在奔跑');
  }
}

mixin Flyer {
  fly() {
    print('在飞翔');
  }
}

// implements的方式要求必须对其中的方法进行重新实现
// class SuperMan implements Runner, Flyer {}

class SuperMain with Runner, Flyer {

}

 6.类成员和方法-----------------static

用static 关键子定义类的变量和函数,只能被类调用不能被对象调用

class Student {
  String name;
  int sno;

  static String time;

  study() {
    print('$name在学习');
  }

  static attendClass() {
    print('去上课');
  }
}

 四.构造方法

机制和C++一样

1.构造方法简化

Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
  // 等同于
  Person(this.name, this.age);

2. 命名构造方法

当既多种不同的构造函数时,可以使用命名构造

class Person {
  String name;
  int age;

  Person() {
    name = '';
    age = 0;
  }
	// 命名构造方法
  Person.withArgments(String name, int age) {
    this.name = name;
    this.age = age;
  }

  @override
  String toString() {
    return 'name=$name age=$age';
  }
}

// 创建对象
var p1 = new Person();
print(p1);
var p2 = new Person.withArgments('why', 18);
print(p2);

 3.重定向构造

一个构造函数调用另一个构造函数

class Person {
  String name;
  int age;

  Person(this.name, this.age);
  Person.fromName(String name) : this(name, 0);//注意这里是this
}

4.常量构造----------------const

某些情况下,我们希望传入相同的值创建的对象是同一个

在构造函数前加一个const

main(List<String> args) {
  var p1 = const Person('why');//实例化的时候也要加const
  var p2 = const Person('why');
  print(identical(p1, p2)); // true
}

class Person {
  //成员变量必须要有final修饰,因为既然是同一个对象那么他的值是不能变得
  final String name;

  const Person(this.name);//构造函数前加const
}

5.工厂构造方法

...没看懂


五.泛型

1.List / Map类型

限定List / Map中的类型

//限定类型为srting 
var names2 = <String>['why', 'kobe', 'james', 111]; // 最后一个报错
List<String> names3 = ['why', 'kobe', 'james', 111]; // 最后一个报错

//姓丁类型为string:string
Map<String, String> infos2 = {'name': 'why', 'age': 18}; // 18不能放在value中
var infos3 = <String, String>{'name': 'why', 'age': 18}; // 18不能放在value中

 2.类泛型

可以在类示例化的时候再指定成员变量类型,定义的时候不指定成员变量变量类型

main(List<String> args) {
  Location l2 = Location<int>(10, 20);
  print(l2.x.runtimeType); // int 

  Location l3 = Location<String>('aaa', 'bbb');
  print(l3.x.runtimeType); // String
}
}

class Location<T> {
  T x;
  T y;

  Location(this.x, this.y);
}

也可以在类定义的时候限定类型 

main(List<String> args) {
  Location l2 = Location<int>(10, 20);
  print(l2.x.runtimeType);
	
  // 错误的写法, 类型必须继承自num
  Location l3 = Location<String>('aaa', 'bbb');
  print(l3.x.runtimeType);
}

class Location<T extends num> {
  T x;
  T y;

  Location(this.x, this.y);
}

 3.泛型方法

使用的时候不用指定类型直接传参

main(List<String> args) {
  var names = ['why', 'kobe'];
  var first = getFirst(names);//直接传参
  print('$first ${first.runtimeType}'); // why String
}

T getFirst<T>(List<T> ts) {
  return ts[0];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值