美文网首页
flutter开发——Dart基本语法学习(下)

flutter开发——Dart基本语法学习(下)

作者: 写代码的小李 | 来源:发表于2022-08-23 20:05 被阅读0次

    一、if、else、else if

      int score = 43;
      
      if(score >= 90){
        if(score == 100){
          print("完美");
        }else{
          print("优秀");
        }
      }else if(score > 60){
        print("良好");
      }else if(score == 60){
        print("及格");
      }else {
        print("不及格");
      }
    

    执行结果:不及格

    二、for、forin

      var list = [1,2,3,4,5];
      for(var index = 0;index < list.length; index++){
        print(list[index]);
      }
      
      for(var item in list){
        print(item);
      }
    

    执行结果:
    1
    2
    3
    4
    5
    1
    2
    3
    4
    5

    三、while、do...while

      int count = 0;
      while(count < 5){
        print(count++);
      }
      
      print("-----------$count-------------");
      
      do{
        print(count--);
      }while(count > 0 && count < 5);
    

    执行结果:
    0
    1
    2
    3
    4
    -----------5-------------
    5
    4
    3
    2
    1

    四、break、continue

      var list1 = [1,2,3];
      for(var item in list1){
        if(item == 2){
          break;
        }
        print(item);
      }
    

    执行结果:1

      var list1 = [1,2,3];
      for(var item in list1){
        if(item == 2){
          break;
        }
        print(item);
      }
    

    执行结果:
    1
    3

    组合使用,循环嵌套

      var list1 = [1,2,3];
      var list2 = [4,5,6];
      for(var item1 in list1){
        if(item1 == 2){
          break;
        }
        for(var item2 in list2){
          if(item2 == 5){
            break;
          }
          print(item2);
        }
      }
    

    执行结果:4
    注意:break只会跳出break所在最内层的循环

    五、switch case

     String language = "Java";
      
      switch(language){
        case "Dart":
          print("Dart is my favorite");
          break;
        case "Java":
          print("Java is my favorite");
          break;
        case "Python":
          print("Python is my favorite");
          break;
        default:
          print("None"); 
      }
      
    

    执行结果:Java is my favorite

    特殊用法:语法——continue+标签
    程序会直接跳转到标签标识的case位置继续执行

      String language = "Java";
      switch(language){
        Tag:
        case "Dart":
          print("Dart is my favorite");
          break;
        case "Java":
          print("Java is my favorite");
          continue Tag;
    
        case "Python":
          print("Python is my favorite");
          break;
        default:
          print("None"); 
      }
    

    执行结果:
    Java is my favorite
    Dart is my favorite

    先执行case "Java",打印:“Java is my favorite”,之后continue Tag,程序跳转到名字为Tag的标签位置,Tag标识在case "Dart"之前,程序便跳转到case "Dart"继续执行,打印:“art is my favorite”

    六、类与对象,声明、创建及基本特征

    1、声明与创建

    • 类与对象
    • 使用关键字class声明类
    • 使用关键字new创建对象,new可省了
    var person = Person();
    

    2、Dart 类的特性

    • 属性默认生成getter和setter方法
    • 使用final声明的属性只有getter方法
    • 属性和方法通过.访问
    • 方法不能被重载
    class Person{
      String name;
      int age;
      void work(){
        print("Name is $name,Age is $age,He is working...");
      }
    }
    
      var person = Person();
      person.age = 12;
      person.name = "tom";
      print(person.age);
      person.work();
    

    3、计算属性

    • 顾名思义,计算属性的值是通过计算而来,本身并不存储值
    • 计算属性的赋值,其实是通过计算转换到其他的实例变量
    class Rectangle{
      num width,height;
      num get area => width * height;
    }
    
      var rect = Rectangle();
      rect.height = 20;
      rect.width = 10;
      
      print(rect.area);//200
    

    七、构造方法及初始化列表

    1、构造方法

    • 如果没有自定义构造方法,则会有个默认构造方法
    • 如果存在自定义构造方法,则默认构造方法无效
    • 构造方法不能重载
    class Boy{
      String name;
      int age;
      Boy(String name, int age){
        this.name = name;
        this.age = age;
        print("Name is $name,Age is $age");
      }
      void work(){
        print("Name is $name,Age is $age,He is working...");
      }
    }
    

    若存在final属性:

    class Boy{
      String name;
      int age;
      final String gender;
      Boy(String name, int age,this.gender){
        this.name = name;
        this.age = age;
        print("Name is $name,Age is $age");
      }
      void work(){
        print("Name is $name,Age is $age,He is working...");
      }
    }
    

    此时属性赋值在构造函数之前执行

    构造方法语法糖:

    Boy(this.name,this.age,this.gender);
    

    同理属性赋值在构造函数之前执行

    命名构造方法:
    由于构造方法无法重载,要想给部分属性赋值时,可以采用赋值构造方法

    class Boy{
      String name;
      int age;
      inal String gender;
      Boy(String name, int age,this.gender){
        this.name = name;
        this.age = age;
        print("Name is $name,Age is $age");
      }
      Boy.withGender(this.gender);
      void work(){
        print("Name is $name,Age is $age,He is working...");
      }
    }
    
      var boy = Boy.withGender("男");
      boy.work();
    

    常量构造方法:

    • 如果类是不可变状态,可以把对象定义为编译时常量
    • 使用const声明构造方法,并且所有变量都为final
    • 使用const声明对象,可以省略
    class Dog{
      final String name;
      final int age;
      const Dog(this.name,this.age);
    }
    

    工厂构造方法:

    • 工厂构造方法类似于设计模式中的工厂模式
    • 在构造方法钱添加关键字factory实现一个工厂构造方法
    • 在工厂构造方法中可返回对象
    class Factory{
      String message;
      factory Factory(String message){
        //message为dart时,实例化,否则返回空
        if(message == "dart"){
          return Factory.internal(message);
        }else{
          return null;
        }
      }
      Factory.internal(this.message);
    } 
    
      var factory = Factory("Java");
      print(factory == null);//true
    

    2、初始化列表

    用于解决构造方法传入集合时,final变量的赋值问题

    • 初始化列表会在构造方法体执行之前执行
    • 使用逗号分隔初始化表达式
    • 初始化列表常用于设置final变量的值
    class Girle{
      String name;
      int age;
      final String gender;
      
      Girle.withMap(Map map) : gender = map["gender"]{
        this.name = map["name"];
        this.age = map["age"]; 
      }
      
      void work(){
        print("Name is $name,Age is $age,Gender is $gender,She is working...");
      }
    }
    
      var map = {"name":"tom","age":12,"gender":"女"};
      var girle = Girle.withMap(map);
      girle.work();
    

    八、静态成员及对象操作符的使用

    1、静态成员

    • 使用static关键字来实现类级别的变量和函数
    • 静态成员不能方位非静态成员,非静态成员可以访问静态成员
    • 类中的常量需要使用static const声明
    class Page{
      static const int maxPage = 10;
      static int currentPage = 1;
      
      static void up(){
        currentPage++;
        print("currentPage = $currentPage");
      }
      
      static void down(){
        currentPage--;
        print("currentPage = $currentPage");
      }
    }
    
    Page.up();//currentPage = 2
    Page.down();//currentPage = 1
    

    2、对象操作符

    条件成员访问:?.
    相当于在执行之前进行判空操作,如果为null则不再执行

      var person;
      person?.age = 12;
    

    此时如果不适用?.则会crash

    类型转换:as

      person = "";
      person = Person();
      (person as Person).age = 12;
    

    是否指定类型:"is & is! "用于判断对象的class

      if(person is Person){
        person.age = 12;
      }
    

    级联操作

      person..name = "小李"
            ..age = 26
            ..work();
    

    九、对象call方法

    如果类实现了call()方法,则该类的对象化可以作为方法使用

    class Animal{
      String call(name,age)=>"Name is $name, age is $age";
    }
    
    var animal = Animal();
    print(animal("小猫",1));//Name is 小猫, age is 1
    

    十、继承、继承中的构造函数

    • 键字extends继承一个类
    • 子类会继承父类可见的属性和方法,不会继承构造方法
    • 子类能够复写父类的方法、getter和setter
    • 单继承
    class Person {
      String name;
      int age;
      String _birthday;
      
      bool get isAdult => age > 18;
      
      void run(){
        print("Person run...");
      }
    }
    
    class Student extends Person{
      
      @override
      bool get isAdult => age > 15;
      
      @override
      void run(){
        print("Student run...");
      }
      
      @override
      String toString(){
        return("Student toString");
      }
      
      void study(){
        print("Student study...");
      }
    }
    
    • 继承中的构造方法
    • 子类的构造方法默认会调用父类无名无参的构造方法
    • 如果父类没有无名午餐的构造方法,则需要显示调用父类构造方法
    • 在构造方法参数后使用:显示调用父类构造方法
    class Person {
      String name;
      int age;
      String _birthday;
      
      bool get isAdult => age > 18;
      
      Person(this.name);
      Person.withName(this.name);
      
      void run(){
        print("Person run...");
      }
    }
    
    class Student extends Person{
      
      Student(String name) : super(name);
    }
    
    
    
    • 构造方法执行顺序
    • 父类的构造方法在子类构造方法体开始执行的位置调用
    • 如果有初始化列表,初始化列表会在父类构造方法之前执行
    class Person {
      String name;
      int age;
      bool get isAdult => age > 18;
      
      Person(this.name);
      Person.withName(this.name);
      
      void run(){
        print("Person run...");
      }
    }
    
    class Student extends Person{
      final String gender;
      Student(String name,String g) : gender = g,super(name);
    }
    

    十一、抽象类

    • 抽象类使用abstract标识,不能直接被实例化
    • 抽象方法不用abstract修饰,无实现
    • 抽象类可以没有抽象方法
    • 有抽象方法的类一定得声明为抽象类
    abstract class Person{
      void run();
    }
    
    class Student extends Person{
      @override
      void run(){
        print("run...");
      }
    }
    

    十二、接口

    • 类和接口是统一的,类就是接口
    • 每个类都隐式定义了一个包含所有实例成员的接口
    • 如果是复用已有类的实现,使用继承(extends)
    • 如果只是使用已有类的外在行为,使用接口(implements)
    class Person {
      String name;
      int age;  
      void run(){
        print("Person run...");
      }
    }
    
    
    class Student implements Person{
      @override
      String name;
      @override
      int age; 
      @override
      void run(){
        print("run...");
      }
    }
    

    建议使用抽象类作为接口

    abstract class Person{
      void run();
    }
    
    class Student implements Person{
      @override
      void run(){
        print("run...");
      }
    }
    

    十三、Mixins,操作符的覆写

    1、Mixins

    • Mixins类似于多继承,是在多类继承中重用一个类代码的方式,Mixin不能直接使用,必须配合继承
    • 作为Mixin的类不能有显示声明构造函数
    • 作为Mixin的类智能继承自Object
    • 使用关键字with连接一个或多个mixin

    顺序问题

    • 如果2个或多个超类拥有相同签名的A方法,那么子类会以继承的最后一个超类中的A方法为准。
    • 若子类也重写了改方法也已子类为准
    • 优先级顺序是:子类自己实现>Mixin>继承,如果有多个Mixin,则已最后的Mixin为主
    class A {
      String getMessage() => 'A';
    }
     
    class B {
      String getMessage() => 'B';
    }
     
    class P {
      String getMessage() => 'P';
    }
     
    class AB extends P with A, B {}
     
    class BA extends P with B, A {}
     
    class C extends P with B, A {
      String getMessage() => 'C'; //优先级最高的是在具体类中的方法。
    }
     
    //关系连接:implements实现、extends继承、with混入
    class CC extends P with B implements A {
      
    } 
    
      var cc = CC();
      print(cc.getMessage());//=>B
    

    使用mixin进行类组合

    abstract class Person{
      String name;
      int age;
      void run();
    }
    
    
    class Animal{
      void eat(){
        print("eat...");
      }
    }
    
    //mixin on的使用,使用这个mixin的class必须继承自Animal
    mixin Boy on Animal implements  Person{
      @override
      String name;
      @override
      int age;
      @override
      void run(){
        print("Person run...");
      }
      
      void playBall(){
        print("playBall...");
      }
    }
    
    mixin Girle implements  Person {
      @override
      String name;
      @override
      int age;
      @override
      void run(){
        print("Person run...");
      }
      
      void dance(){
        print("dance...");
      }
    }
    
    
    class Cat{
      void eat(){
        print("eat...");
      }
    }
    
    

    此时我们可以使用快捷方式组合class

    class A = Cat with Girle;
    
    var a = A();
    a.run();
    

    2、操作符的覆写

    • 操作符覆写
    • 覆写需要在类中定义
    返回类型 operator操作符(参数1、参数2.....){
         实现体
         return 返回值
    }
    
    class Person {
      int age;
      bool operator > (Person person){
        return this.age > person.age;
      }
    }
    
      var p1= Person();
      p1.age = 18;
      var p2= Person();
      p2.age = 13;
      
      print(p1>p2);//ture
    

    十四、方法

    1、方法定义

    • 法也是对象,并且有具体类型Function
    • 返回类型、参数类型都可以省略
    • 箭头语法:=> expr 是{return expr;}缩写。只适用于一个表达式
    • 方法都有返回值。如果没有制定,默认return null左后一句执行
    //方法也是对象,并且有具体类型Function
    String getPerson(String name, int age){
      return "名字:$name,年龄:$age";
    }
    
    printPerson(name,age){
      print("名字:$name,年龄:$age");
    }
    
    //=>语法
    
    getPerson1(name, age) => "名字:$name,年龄:$age";
    
    
      print(getPerson('张三',12));
      printPerson('张三',12);
      print(getPerson1('张三',12));
    

    2、可选参数

    • 可选命名参数:{param1,param2,…}
    • 可选位置参数:[param`,param2,…]
    //1、可选命名参数{param1,...}  
    printPersionOptional1(name,{age,gender}) => "名字:$name,年龄:$age,性别:$gender";
    
    //2、可选位置参数[param1,...]
    printPersionOptional2(name,[age,gender]) => "名字:$name,年龄:$age,性别:$gender";
    
    

    注意:可选参数必须在具体参数之后!!!

    3、默认参数

    • 使用=在可选参数指定默认值
    • 默认值只能是编译时常量
    //默认参数
    printPersionOptionalDefault(name,{age=12,gender="男"}) => "名字:$name,年龄:$age,性别:$gender";
    
    
    

    归纳代码:

    
    //要达到可选命名参数的用法,那就在定义函数的时候给参数加上 {}
    void enable1Flags({bool bold, bool hidden}) => print("$bold , $hidden");
    
    //定义可选命名参数时增加默认值
    void enable2Flags({bool bold = true, bool hidden = false}) => print("$bold ,$hidden");
    
    //可忽略的参数在函数定义时用[]符号指定
    void enable3Flags(bool bold, [bool hidden]) => print("$bold ,$hidden");
    
    //定义可忽略参数时增加默认值
    void enable4Flags(bool bold, [bool hidden = false]) => print("$bold ,$hidden");
    
    //可选命名参数函数调用
    enable1Flags(bold: true, hidden: false); //true, false
    enable1Flags(bold: true); //true, null
    enable2Flags(bold: false); //false, false
    
    //可忽略参数函数调用
    enable3Flags(true, false); //true, false
    enable3Flags(true,); //true, null
    enable4Flags(true); //true, false
    enable4Flags(true,true); // true, true
    
    

    4、对象方法

    • 方法可作为对象赋值给其他变量
    • 方法可作为参数传递给其他方法
    void printHrello(){
      print("Hello");
    }
    
    void printDoubleNumber(num){
      print(num*5);
    }
    
    
    List listTimes(list,times(str)){
      for(var index = 0; index < list.length; index ++){
        list[index] = times(list[index]);
      }
      return list;
    }
    
    List listTimes1(list){
      var fun = (str)=>str*3;
      for(var index = 0; index < list.length; index ++){
        list[index] = fun(list[index]);
      }
      return list;
    }
    
    times(str) => str*3;
    
    
    
      Function func = printHrello;
      func();
      
      var list = [1,2,3,4];
      //forEach接收一个Function类型的参数
      list.forEach(print);
      list.forEach(printDoubleNumber);
      
      print(listTimes(['a','b','c','d'],times));
    
    

    执行结果:

    Hello
    1
    2
    3
    4
    5
    10
    15
    20
    [aaa, bbb, ccc, ddd]
    
    

    5、匿名方法

    匿名方法特征:

    • 可赋值给变量,通过变量进行调用
    • 可在其他方法中直接调用或传递给其他方法
      //匿名方法
      var func = (str){
        print('======= $str');
      };
      func("Hlelo");
      
      //匿名方法直接执行
      ((){
        print('=======');
      })();
      
      
      print(listTimes(['a','b','c','d'],(str)=>str*5));
      print(listTimes1(['a','b','c','d']));
    
    

    6、闭包

    • 闭包是一个方法(对象)
    • 闭包定义在其他方法内部
    • 闭包能够访问外部方法内的局部变量,并持有其状态
    a(){
      int count = 0;
      printCount(){
       print(count++);
      }
      return printCount;
    }
    
    
      var func = a();
      func();
      func();
      func();
      func();
    
    

    执行结果:

    0
    1
    2
    3
    
    

    另一种写法:

    a(){
      int count = 0;
    //   printCount(){
    //    print(count++);
    //   }
      return (){
        print(count++);
      };
    }
    
    

    执行结果仍然是:

    0
    1
    2
    3
    
    

    十五、枚举

    1、枚举是一种有穷序列集的数据类型
    2、使用关键字enmu定义一个枚举
    3、常用于代替常量,控制语句等

    enum Season{
      spring,
      summer,
      autumn,
      winter
    }
    
    void main() {
      var currentSeason = Season.spring;
      switch(currentSeason){
        case Season.spring:
          print("1-3月");
          break;
        case Season.summer:
          print("4-6月");
          break;  
        case Season.autumn:
          print("7-9月");
          break;
        case Season.winter:
          print("10-12月");
          break;
      }
    }
    

    index从0开始,依次累加

     var currentSeason = Season.spring;
     print(currentSeason.index);//0
    

    注意:Dart中枚举不能指定原始值,不能添加方法!!

    十六、泛型

    1、Dart中类型是可选的,可使用泛型限定类型
    2、使用泛型能够有效的减少代码重复

    类的泛型:在类名后定义

    void main() {
      var utils1 = new Utils1<int>();
      utils1.put(1 );
    }
    
    class Utils1<T>{
      T element;
      
      void put(T element){
        this.element = element;
      }
    }
    

    方法的泛型:在方法名后定义

    void main() {
     var utils2 = new Utils2();
      utils2.put<String>("1");
    }
    
    class Utils2{
      void put<T>(T element){
        print(element);
      }
    }
    
    
    

    相关文章

      网友评论

          本文标题:flutter开发——Dart基本语法学习(下)

          本文链接:https://www.haomeiwen.com/subject/xitsgrtx.html