Dart基础学习总结(中)

本文深入讲解Dart语言的函数定义、调用、参数传递、作用域、递归、闭包等核心概念,同时覆盖类的创建、使用、构造函数、私有属性与方法,以及Dart面向对象编程的基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Dart中的函数  函数的定义 可选参数  默认参数  命名参数 箭头函数 匿名函数 闭包

 内置方法/函数:就是系统自带的方法,比如一直用的打印方法:  print();

 自定义方法:

Dart中的函数的调用

方法的作用域

Dart中调用方法传参

Dart中的箭头函数

Dart中方法间的互相调用

Dart中的匿名函数

Dart中的自执行方法

Dart中方法的递归

Dart中的闭包

Dart面向对象的介绍 以及Data内置对象

 Dart中自定义类的创建和使用

Dart中自定义类的默认构造函数

Dart中自定义类的命名构造函数

Dart中把类单独抽离成一个模块

Dart中的私有方法 和私有属性

类中的get和set修饰符的用法

类中的初始化列表


Dart中的函数  函数的定义 可选参数  默认参数  命名参数 箭头函数 匿名函数 闭包

Dart中的函数分为两种,内置函数和自定义函数。

 内置方法/函数:就是系统自带的方法,比如一直用的打印方法:  print();

 自定义方法:

      自定义方法的基本格式:

      返回类型  方法名称(参数1,参数2,...){

        方法体

        return 返回值;

      }

如:

//一个无返回类型的自定义方法
void printInfo(){
  print('我是一个自定义方法');
}

//一个有返回类型的自定义方法
int getNum(){
  var myNum=123;
  return myNum;
}

自定义方法可以写在main()方法里,也可以现在main方法外,void表示是无返回类型的方法,返回类型可以是任意类型,但是需要与返回值保持一直:

//返回类型为String的函数
String printUserInfo(){
  return 'this is str';
}

//返回类型为List的函数
List getList(){
  return ['111','2222','333'];
}

Dart中的函数的调用

在dart中所有函数都要在入口函数main()中执行

如:(main()中的方法皆为上文中定义出来的方法)

void main(){

   print('调用系统内置的方法');

   printInfo();

   var n=getNum();

   print(n);

   print(printUserInfo());
 
   print(getList());

}

方法的作用域

void main (){
  void xxx(){
      aaa(){
          print(getList());
          print('aaa');
      }
      aaa();
  }
  // aaa();  错误写法,超出aaa()方法的作用域
  xxx();  //调用方法
  }
}

如上所示,方法内是可以嵌套方法的,但是在xxx()方法内定义的方法,只可以在本方法内部调用,如果写在外面,会提示找不到该方法;但是可以在aaa()中调用getList()方法,因为getList()的作用域是全局的;

Dart中调用方法传参

1、定义一个方法 求1到这个数的所有数的和

int sumNum(int n){//一般建议规定好参数类型
      var sum=0;
      for(var i=1;i<=n;i++)
      {
        sum+=i;
      }
      return sum;
    } 

    var n1=sumNum(5);//传入参数5,即显示1到5的和
    print(n1);//输出结果:15
    var n2=sumNum(100);//传入参数5,即显示1到100的和
    print(n2);//输出结果:5050

2、定义一个方法然后打印用户信息

 String printUserInfo(String username,int age){  //形参
         return "姓名:$username---年龄:$age";
     }

     print(printUserInfo('张三',20)); //实参
    //输出结果:姓名:张三---年龄:20

写在方法里的参数,称为形参,具体传入的参数,称为实参;

3、定义一个带可选参数的方法

String printUserInfo(String username,[int age]){  写在[]里的参数,为可选参数

       if(age!=null){
         return "姓名:$username---年龄:$age";
       }
       return "姓名:$username---年龄保密";
     }

     print(printUserInfo('张三',21)); //输出结果:姓名:张三---年龄:21

     print(printUserInfo('张三'));//输出结果:姓名:张三---年龄保密

4、定义一个带默认参数的方法

String printUserInfo(String username,[String sex='男',int age]){//[]中的参数如果有默认值,则为默认参数 
       if(age!=null){
         return "姓名:$username---性别:$sex--年龄:$age";
       }
      return "姓名:$username---性别:$sex--年龄保密";
     }
print(printUserInfo('张三'));//输出结果: 姓名:张三---性别:男--年龄保密

5、定义一个命名参数的方法

String printUserInfo(String username,{int age,String sex='男'}){  //注意:这里是{}

      if(age!=null){
        return "姓名:$username---性别:$sex--年龄:$age";
       }
       return "姓名:$username---性别:$sex--年龄保密";
  }
  print(printUserInfo('张三',age:20,sex:'未知'));//{}中的参数也可选填,但是要传参时需要"参数名:参数"这样的格式
//输出结果:姓名:张三---性别:未知--年龄:20

6、实现一个 把方法当做参数的方法

  fn1(){
    print('fn1');
  }
  //方法
  fn2(fn){
    
    fn();
  }
  //调用fn2这个方法 把fn1这个方法当做参数传入
  fn2(fn1);//输出结果:fn1

Dart中的箭头函数

方法体中只能写一句话,例如

使用forEach打印下面List里面的数据:常规写法

     List list=['苹果','香蕉','西瓜'];

     list.forEach((value){
       print(value);
     });

改为箭头函数:

 List list=['苹果','香蕉','西瓜'];

 list.forEach((value)=>print(value));

或者

 List list=['苹果','香蕉','西瓜'];
  list.forEach((value)=>{
     print(value)//注意,这里不写 ;
     });

Dart中方法间的互相调用

需求:定义一个方法打印1-n以内的所有偶数

思路:定义一个方法isEvenNumber来判断一个数是否是偶数  ,再定义一个方法printNum()来输入要打印的范围;

    bool isEvenNumber(int n){
      if(n%2==0){
        return true;
      }
      return false;
    }

    printNum(int n){
        for(var i=1;i<=n;i++){
            if(isEvenNumber(i)){
              print(i);
            }
        }
    }

    printNum(10);

这样,就实现了方法间的互相调用

Dart中的匿名函数

一般定义函数都是有名字的,如之前定义的isEvenNumber(int n),而匿名函数的语法格式如下:

void main(){
   
  //不带参数的匿名方法
   var printNum=(){
     print(123);

   };
   printNum();

  //带参数的匿名方法
   var printNum=(int n){
     print(n+2);
   };
   printNum(12);

使用的方法和普通函数一样。

Dart中的自执行方法

自执行方法:顾名思义,就是不用主动去调用,让这个程序一加载就自己执行的方法。

 语法格式:使用两个(),在第一个括号里写一个匿名函数,其中前面的括号里定义形参,第二个()里传入实参

     ((int n){

       print(n);
       print('我是自执行方法');

     })(66);

打印结果:66 我是自执行方法

Dart中方法的递归

递归及一个方法调用自己,注意要设置结束调用的填写

需求1:求n的阶乘

示例代码:

       var sum=1;       
       fn(n){
           sum*=n;
           if(n==1){
             return ;
           }        
          fn(n-1);       
       }

       fn(5);     
       print(sum);

需求2:求n的阶乘通过方法的递归 求1-100的和

    var sum=0;

    fn(int n){
        sum+=n;
        if(n==》=100){//设置结束递归的条件
          return //设置要返回的值
        }
       fn(n-1);
    }

    fn(100);
    print(sum);//输出结果:5050

Dart中的闭包

了解闭包之前,先看全局变量和局部变量的特点:

    1、全局变量特点:    全局变量常驻内存、全局变量污染全局(即不会被垃圾回收机制回收,而且可以被其他的函数引用,修改,容易造成程序里未知错误);

    2、局部变量的特点:  不常驻内存会被垃圾机制回收、不会污染全局 

所以如果想常驻内存又不想不污染全局时,就有了闭包的操作;  

那什么是全局变量和局部变量呢?

例如:

/*全局变量演示*/
var a=12;

void main(){

     print(a);
     fn(){
       a++;
       print(a);
     }

     fn();//输出结果:13
     fn();//输出结果:14
     fn();//输出结果:15
//由此可见,a是常驻内存的,因此像这样的变量,称为全局变量

//局部变量演示

   printInfo(){
   var myNum=13;//其中myNum就是局部变量。他的作用域仅限于这个方法,在这个方法外不能被调用 
       myNum++;
       print(myNum);
     }

     printInfo();//输出结果:14
     printInfo();//输出结果:14
     printInfo();//输出结果:14
/*可以看到,每次调用完printInfo()方法后,myNum就被回收了,下次调用的时候,又是一个新的myNum,
所以每次结果都14,即13+1,这样的变量称为局部变量*/

         闭包: 函数嵌套函数, 内部函数会调用外部函数的变量或参数, 变量或参数不会被系统回收(不会释放内存)

         闭包的写法: 函数嵌套函数,并return 里面的函数,这样就形成了闭包。

示例代码:

  printInfo(){
    var myNum=13;
    return(){//这里其实是一个匿名函数
      myNum++;
      print(myNum);
    };
  }

  var b = printInfo();//定义一个变量b来接受返回的函数
  b();//输出结果:14
  b();//输出结果:15
  b();//输出结果:16
/*可以看到,myNum是一个局部变量,不会污染全局。但是每次调用结束的时候,也不会被系统回收,
这样就完成了闭包*/

Dart面向对象的介绍 以及Data内置对象

面向对象编程(OOP)的三个基本特征是:封装、继承、多态     

      封装:封装是对象和类概念的主要特性。封装,把客观事物封装成抽象的类,并且把自己的部分属性和方法提供给其他对象调用, 而一部分属性和方法则隐藏。               

      继承:面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

      多态:允许将子类类型的指针赋值给父类类型的指针, 同一个函数调用会有不同的执行效果 。

Dart所有的东西都是对象,所有的对象都继承自Object类。

Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类

一个类通常由属性和方法组成。

/*
比如之前用到过的List,Map等,其本质就是一个类
*/
void main(){   

    List list=new List();
    list.isEmpty;
    list.add('香蕉');
    list.add('苹果');
/* 比如,在List类中,为我们提供了.add(),.isEmpty()等方法*/

    Map m=new Map();
    m["username"]="张三";
    m.addAll({"age":20});
    m.isEmpty;

    Object a=123;
    print(a);
}

 Dart中自定义类的创建和使用

我们来自定义一个Person类。


 class Person{//使用关键字class来定义一个类
  String name="张三";//为person类添加一个属性name;
  int age=23;

  void getInfo(){//定义一个方法getInfo()来打印这个类里的属性;
    //两种引用属性的方法
      print("$name----$age");
      print("${this.name}----${this.age}");//this关键字表示当前类

  }
  void setInfo(int age){//定义一个方法setInfo()来为这个类里的属性赋值;
    this.age=age;
  }

}
//类的使用
void main(){
  //首先必须实例化,在dart中,new关键字可以省略。
   var p1=new Person();
   //如果像调用类里面的name属性,那么就可以直接用p.name获取,获取方法同理
   print(p1.name);//输出结果:张三
   p1.getInfo();//输出结果:张三 ----23

  
  Person p2=new Person();
  //同时,也可以通过类里的方法,对属性进行修改
  p1.setInfo(28);//调用setInfo方法,修改age的值

  p1.getInfo();//输出结果:张三 ----28
}

Dart中自定义类的默认构造函数

默认构造函数一般和类同名,并且在实例化的时候自动被调用,如:

 class Person{
   String name='张三';
   int age=20;
   //默认构造函数
   Person(){
     print('这是构造函数里面的内容  这个方法在实例化的时候触发');
   }
   void printInfo(){  
     print("${this.name}----${this.age}");
   }
 }

void main(){
   /*此时,只要实例化Person类后,就会输出内容:
    '这是构造函数里面的内容  这个方法在实例化的时候触发'*/
   var p1=new Person();
}

如果想让Person类打印任何人的信息,就可以这样写:

 class Person{
   String name;
   int age;

   //默认构造函数
   Person(String name,int age){
       this.name=name;
       this.age=age;
   }
   void printInfo(){  
     print("${this.name}----${this.age}");
   }
 }
//此时,在main方法中实例化Person类的时候,就需要传入要打印的信息,如:
void main(){

   var p1=new Person(’张三’,12);
   p1. printInfo();//输出结果:张三----12
//类可以进行多次实例化,比如现在又想打印李四的信息,只要在初始化一个对象p2
    var p2 = Person('李四',34)    
    p2.printInfo();//输出结果:李四----34
}

默认构造函数的简写

class Person{
  String name;
  int age;
  //默认构造函数的简写
  Person(this.name,this.age);
  void printInfo(){  
    print("${this.name}----${this.age}");
  }
}

Dart中自定义类的命名构造函数

dart里面构造函数可以写多个,但是默认构造函数只能写一个,语法

类名.方法名(){};如:

class Person{

  String name;
  int age;

  //默认构造函数
  Person(this.name,this.age);

  //命名构造函数
  Person.now(){
    print('我是命名构造函数');
  }

  //命名构造函数
  Person.setInfo(String name,int age){
    this.name=name;
    this.age=age;

  }

  void printInfo(){  
    print("${this.name}----${this.age}");
  }

}


void main(){
   var d=new DateTime.now();   //实例化DateTime调用它的命名构造函数
   print(d);

  Person p1=new Person('张三', 20);   //默认实例化类的时候调用的是 默认构造函数
  Person p1=new Person.now();   //命名构造函数

  Person p2=new Person.setInfo('李四',30);
  p2.printInfo();
}

Dart中把类单独抽离成一个模块

在实际开发中,为了可维护性,一般会将一个类抽离出来一个单独的.dart文件。这样做的好处就是,可以在任意地方,通过import关键字来导入这个类就可以使用,单个文件内代码也不会过于冗余。便于多人开发。

如:我在lib文件夹下,新建一个Person.dart文件,将刚才Person类的内容剪贴进去

使用的时候:

import 'lib/Person.dart';

void main(){
  Person p1=new Person.setInfo('李四',30);
  p1.printInfo();//输出结果:李四----30
}

我在使用AndroidStudio时,虽然将文件放在了lib目录下,但是import的路径为:'package:项目名/Person.dart';

Dart中的私有方法 和私有属性

Dart和其他面向对象语言不一样,Data中没有 public  private protected这些访问修饰符号,但是我们可以使用_把一个属性或者方法定义成私有。

首先我们新建一个Animal类:

class Animal{
  String _name;   //私有属性
  int age;
  //默认构造函数的简写

  Animal(this._name,this.age);

  void printInfo(){  
    print("${this._name}----${this.age}");
  }

  void _run(){
    print('这是一个私有方法');
  }

}

这样name属性和run()方法都是私有方法,私有的方法和属性不能直接被调用,只能在方法内调用。因此我们需要在类里在定义几个方法,来间接的获取私有方法和属性。

class Animal{
  String _name;   //私有属性
  int age;
  //默认构造函数的简写

  Animal(this._name,this.age);

  void printInfo(){  
    print("${this._name}----${this.age}");
  }

  String getName(){
    return this._name;
  }

  void _run(){
    print('这是一个私有方法');
  }

  execRun(){
    this._run();  //类里面方法的相互调用
  }

}

通过添加方法getName()和 execRun(),就可以在main()中调用Animal内的私有属性和方法,如:

void main(){

 Animal a=new Animal('小狗', 3);
 
 //print(a._name)这样写,程序会报错,因为_name为私有属性,只能在Animal类里被调用
//此时需要调用公共方法getName()来间接的调用私有属性
 print(a.getName());
 a.execRun();   //间接的调用私有方法
}

类中的get和set修饰符的用法

我们定义一个Rect类,在Rect中有输出面积和输入长宽的方法。使用get定义的时候,方法后面没有(),相当于计算属性,调用的时候跟调用属性的方式一样。set使用和get类似。下面是常规写法和使用get/set的对比:

 class Rect{
  num height;
  num width;  

  Rect(this.height,this.width);
 //常规方法定义
  area(){
     return this.height*this.width;
  }
  //使用get定义方法:
  get area{
     return this.height*this.width;
   }

 //使用set定义方法
 set areaHeight(value){
    this.height=value; 
  }
 }

定义方式不同,调用的方式也会不同:

 void main(){

   Rect r=new Rect(10,4);

   print("面积:${r.area()}");  //常规调用方法

   print("面积:${r.area}");   //注意调用直接通过访问属性的方式访问area
   r.areaHeight=6; //调用使用set定义的方法,也相当于一个属性
   print("面积:${r.area}"); //在打印时就会输出:60
 }

类中的初始化列表

 Dart中我们也可以在构造函数体运行之前初始化实例变量

class Rect{
  int height;
  int width;

  Rect():height=2,width=10{//初始化列表操作
    print("${this.height}---${this.width}");
  }

  getArea(){
    return this.height*this.width;  }
}

void main(){

  Rect r=new Rect();//此时,就会输出2----10,说明在实例化之前,就已经给属性赋值了

  print(r.getArea());

}

 

上一篇:Dart基础学习总结(上)

下一篇:Dart基础学习总结(下)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值