安装
Dart官网
安装brew
Brew安装
执行代码
代码语言:javascript复制/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
使用BREW安装Dart的SDK
代码语言:javascript复制$ brew tap dart-lang/dart
$ brew install dart
- 安装的过程如果有代理的,需要将代理关掉,不然会提示安装失败
检测Dart是否安装成功:dart info
使用vscode编写dart文件
- 需要安装两个插件:code runner 和 Dart
至此就可以使用您的电脑开发Dart了
认识Dart
Dart这门语言比较奇葩一点,他拥有很多java的特性,但是写法却和js很像,学习这门语言的根本目的也是不得已而为之,毕竟学习flutter的话,dart不学习是不行的,这篇文章就是简单的写一下dart中我们需要注意的一些点,和js以及java的不同之处,如果您有java和js的基础的话,那么学习这门语言将会异常的简单。这篇文章写的比较简单,包括demo写的都是一些超级简单的,目的很明确,了解dart这门语言就可以,具体说我们使用其实要结合flutter进行使用,同时我个人认为的是这篇文章的人都是有js或者java或者两者都有基础的人阅读的,所以是没有什么压力的。本片章重点介绍和和js以及java中的一些出入,避免这些出入以后可以说Dart就已经会使用了!
基本语法概述
基本的写法和js保持一致,写一个简单的demo,包含了基本的写法,强调几个点和js的区别
- 常量:和js语法一致,均是使用const,但是多了一个final进行声明,比如:const pi = 3.1415 Or final PI = 3.14
- Dart是一种相对智能的语言,有自己的语法检测,比如定义了string类型,在后面重新赋值了int类型的情况会提示错误。
- Dart是区分大小写的,var str 和var STR 是两个变量
- Dart是严格使用分号的,结尾不加分号会报错
- 和js语法基本一致,可以使用var声明,Dart会根据赋值来判断类型,但是不支持Js的let声明,也同样适应java语法,使用数据类型进行声明,比如:String str = ‘hello’ int Num = 1234等
- Dart获取值是通过“${变量}”进行获取
- Dart中万物皆是Object
//自定义无参函数
int num() {
return 123;
}
//自定义必填参数函数
String UserInfos(String name, int age) {
return "姓名:$name 年龄:$age";
}
//自定义非必填参数函数 默认返回的是null 可选参数可以是多个,全部写在[]里面即可 当然也可以在参数里面直接默认赋值
String getUserInfos(String name, [String sex]) {
if (sex != null) return "姓名:$name 性别:$sex";
return "姓名:$name 性别保密";
}
//自定义一个命名参数
String ObjUserInfos(String name, {String sex}) {
return "姓名:$name 性别:$sex";
}
//入口函数
void main() {
print(num());
print(UserInfos("tom", 25));
print(getUserInfos("tom"));
print(ObjUserInfos("tom", sex: '男'));
}
main方法
这个是dart语言的最最最主要的一个方法,也是所有函数执行的入口函数,和java中的main方法以及c语言中的main函数拥有一样的位置,这里的重要性就不需要再提了吧!
变量、常量
变量就是可变的量,比如定义了一个String name name就是一个变量,常量就是不可以改变的量,const pi = 3.14, pi就是一个常量
函数
将一段实现某一个功能的一段代码进行封装起来的方法就是函数
静态
代码语言:javascript复制静态属性和方法,使用static进行修饰的属性和方法就叫做静态属性和方法,直接通过类进行调用,静态方法不可以访问非静态的成员,但是非静态的方法可以访问静态的成员
class Info {
String name;
int age;
static String sex;
infoFun() {
return this.name; //使用this访问的是非静态属性
}
//静态方法不可以访问非静态的属性和方法
static String staFun() {
return sex; //不需要this,直接使用属性,调用静态方法也是一样的,直接调用就可以
}
}
void main() {
var i = new Info();
i.name;
i.age;
Info.sex; //静态的属性直接使用类进行访问
}
默认的get、set方法
代码语言:javascript复制和普通的方法的区别就是调用的时候需不需要加小括号
class Areafun {
int height;
int width;
//构造函数第一种默认值的写法
//Areafun(this.height, this.width) {}
//构造函数第二种默认值有值的写法
Areafun()
: this.height = 10,
this.width = 4 {}
//还有一种默认的get set方法
get areavalue {
return this.height * this.width;
}
//默认的set方法
set areaNewValue(int value) {
this.height = value;
}
comArea() {
return this.height * this.width;
}
}
void main() {
var area = new Areafun();
print(area.comArea());
print(area.areavalue); //此时不需要加小括号
area.areaNewValue = 45;
print(area.areavalue);
}
闭包
代码语言:javascript复制了解闭包之前先要了解一下什么是局部变量和全局变量,这里就说一下他们各自的特点,具体什么是全局变量和局部变量,看文章的人没有不知道的应该,全局变量:常驻内存,污染全局,局部变量:不会常驻内存,会被垃圾回收,不会污染全局,让一个变量常驻内存,但是又不污染全局,这个就是闭包的意义所在,实现一个闭包也很简单,函数嵌套函数,内部函数调用外部函数的变量或者参数,并return 里面的函数就形成了闭包
void main() {
printInfo() {
var a = 123;
return () {
a ;
print(a);
};
}
var b = printInfo();
b();
b();
b();
}
递归
代码语言:javascript复制下面的demo里面有匿名函数,递归函数,和自执行函数,所谓的递归就是轮循自己进行一些功能的实现,通过某一个条件进行终止自身的循环的一种写法
//匿名函数
var num = (int n) {
return n;
};
//递归函数
var sum = 1;
fn(int n) {
sum *= n;
if (n == 1) {
return false;
}
fn(n - 1);
}
//入口函数
void main() {
print(num(12));
//自执行函数
(() {
print('is Run');
})();
//调用
fn(8);
print(sum);
}
操作符
代码语言:javascript复制? 条件运算符 as 类型转换 is 类型判断 …级联操作(连缀),下面的demo主要演示连缀的操作,别的基本和js是一致的。
class Info {
String name;
int age;
Info(this.name, this.age) {}
printInfo() {
print("${this.name}:${this.age}");
}
}
void main() {
//常规写法
var p = new Info('张三', 20);
p.name = 'tom';
p.age = 26;
p.printInfo();
//连缀写法
p
..name = 'jim'
..age = 30
..printInfo();
}
类
代码语言:javascript复制Dart是一门面向对象编程的语言,它具有封装、继承、多态的特性,Dart是一门使用类和单继承的面向对象的语言,所有的对象都是类的实例,并且所有的类都是Object的子类,Dart中所有的东西都是对象,所有的对象都是继承自Object类,类:属性和方法组成:比如系统的List,Map都属于类
class Person {
String name = 'tom';
int age = 23;
//构造函数
// Person() {
// print("我是构造函数,我被实例化的时候就会执行");
// }
Person(this.name, this.age) {
print("我是构造函数,我被实例化的时候就会执行");
}
//命名构造函数可以第一多个
Person.now() {
print("我是命名构造函数,我被实例化的时候就会执行");
}
Person.setInfo(name, age) {
print("我是命名构造函数,我被实例化的时候就会执行");
}
setInfo(int age) {
this.age = age;
}
getInfo() {
print('${this.name} , ${this.age}');
}
}
封装、私有变量、公有变量以及构造函数
代码语言:javascript复制似有变量就是只能在自己的类中使用,在被引入的文件中是不可以被调用的,共有的变量就是,可以在自身类中被调用意外,还可以在被引入的时候调用,构造函数是在该类被初始化的时候就开始进行执行的函数,这里为什么将封装也写到这里了呢?因为私有变量在dart的封装性中可以得以体现!
//这是一个具有私有变量的类,似有变量是在前面加上下划线
class Animal {
String _name; //此时的name是似有变量
int _age;
String sex; //这个不加下划线的时候是一个共有的方法
Animal() {
print("我是初始化的时候就会执行的构造函数");
}
// 此时的getInfo的函数是一个共有的函数,可以将私有的属性return出去为共有的属性
String getInfo() {
return this._name;
}
//这是一个私有的函数
void _run() {
print('我是一个私有的函数');
}
//这是一个共有的函数,执行的是一个私有的函数
execFun() {
this._run();
}
}
//另一个文件可以通过import进行引入
import 'lib/Animal.dart';
void main() {
Animal a = new Animal();
a.sex;
a.execFun();
}
继承
代码语言:javascript复制通过extends进行实现,继承以后,子类拥有了父类的方法和属性,但是需要注意的是如果父类中拥有构造函数的话,子类继承的父类的时候需要将构造函数实现掉,当然子类也可以重写父类的方法,不过这里有一个常规的约定就是你可以直接实现父类方法一样的名字,但是一般我们都加上@override关键字
class Person {
String name = 'tom';
int age;
String getInfo() {
return this.name;
}
}
//Child 继承了Person类,进而得到了Person的属性和方法,当然这是没有构造函数的情况
class Child extends Person {}
//具有构造函数的类
class Man {
String name;
int age;
String sex;
String getInfo() {
return this.name;
}
//构造函数
Man(this.name, this.age) {}
}
class Boy extends Man {
Boy(String name, int age, String sex) : super(name, age) {
this.sex = sex;
}
String exec() {
print("${this.name} --- ${this.age} --- ${this.sex}");
}
}
//复写父类的方法
class Animal {
String name = 'Dog';
void info() {
print("${this.name}");
}
}
class Dog extends Animal {
String name = 'sheep';
//重写父类的方法 这里不加@override也是可以的,一般会加上
@override
void info() {
print("${this.name}");
}
}
//子类调用父类的方法
class Factory {
String name = 'FAC';
void run() {
print('this is FAC');
}
}
//通过super关键字调用
class Famer extends Factory {
void info() {
super.run();
}
}
void main() {
Child c = new Child();
print(c.name);
Boy b = new Boy('tom', 20, '男');
b.exec();
Dog d = new Dog();
d.info();
Famer f = new Famer();
f.info();
}
多态
这里的多态可以通过继承、实现、mixins进行体现。
封装
上面将类单独抽离出去经过import进行引入的过程就是封装的过程,
抽象类
代码语言:javascript复制通过abstract进行定义抽象类,抽象类一般用于定义标准,抽象类不可以被实例化,只有被他继承的子类可以被实例化,如果子类继承类抽象类,就必须实现抽象类里面的方法 定义一个抽象类 包含一个抽象方法 用于约束子类
abstract class Animal {
eat();
printInfo() {
print('我是一个普通抽象类里面的普通方法');
}
}
class Dog extends Animal {
@override
eat() {
// TODO: implement eat
print('my name is animal');
}
}
class Cat extends Animal {
@override
eat() {
// TODO: implement eat
throw UnimplementedError();
}
}
void main() {
Dog d = new Dog();
d.eat();
d.printInfo();
}
接口和实现
代码语言:javascript复制dart中没有interface关键字,我们一般使用类进行定义接口,常规的写法是使用抽象类进行接口的定义,通过implates进行实现,接口就是约定一些类的规范和方法,这里的接口可能和对java有深刻认知的人有点出入,java中定义接口是使用interface关键字进行定义一个类的,但是dart中是使用抽象类进行定义接口,当然你也可以使用普通的类进行定义接口
abstract class Db {
String uri; //数据库的链接地址
add(); //数据库的增加方法
del(); //数据库的删除方法
update(); //数据库的更新方法
search(); //数据库的查询方法
}
abstract class Language {
String name;
}
class Mysql implements Db {
@override
String uri;
@override
add() {
// TODO: implement add
print('this is mysql');
}
@override
del() {
// TODO: implement del
throw UnimplementedError();
}
@override
search() {
// TODO: implement search
throw UnimplementedError();
}
@override
update() {
// TODO: implement update
throw UnimplementedError();
}
}
class Oracle implements Db {
@override
String uri;
@override
add() {
// TODO: implement add
print('this is oracle');
}
@override
del() {
// TODO: implement del
throw UnimplementedError();
}
@override
search() {
// TODO: implement search
throw UnimplementedError();
}
@override
update() {
// TODO: implement update
throw UnimplementedError();
}
}
//实现多个接口的时候,要同时实现里面的方法
class Impl implements Db, Language {
@override
String name;
@override
String uri;
@override
add() {
// TODO: implement add
throw UnimplementedError();
}
@override
del() {
// TODO: implement del
throw UnimplementedError();
}
@override
search() {
// TODO: implement search
throw UnimplementedError();
}
@override
update() {
// TODO: implement update
throw UnimplementedError();
}
}
void main() {
Mysql m = new Mysql();
m.add();
Oracle o = new Oracle();
o.add();
}
mixins
代码语言:javascript复制在dart中可以实现类似多继承的功能,但是他不是多继承,因为只可以单继承,多实现,mixins是一种新特性,但是喜欢vue的人可能就模糊了,vue中也有这个,但是那个是为了混入一些公共的方法,这里也可以这么理解,类的目的也是为了处理功能的一块代码,为了别的类也可以使用,根源是一样的。 作为被mixins的类,不可以是继承的类,也就是说如果他已经继承类别的类,那么他就不可以被mixins了 被minxin的类不可以有构造函数,如果有多个同样的方法的时候,with后面的函数会最后被执行,也就是最后的会替代前面的同名的函数 子类可以继承父类同时进行mixins别的父类
class A {
printInfoA() {
print('this is A');
}
}
class B {
printInfoB() {
print('this is B');
}
}
class D {
D() {}
printInfoD() {
print('this is D');
}
}
//可以实现继承和mixins同时使用
class C extends D with A, B {}
void main() {
C c = new C();
c.printInfoA();
}
泛型
代码语言:javascript复制为了解决类,方法,接口,的复用性,以及对不特定类型的支持(数据校验),通过T【当然你也可以使用别的字母进行,只是我们默认使用的是T】关键字进行泛型的定义
//定义一个泛型的方法
T getData<T>(T value) {
return value;
}
//定义一个泛型类
class PrintClass<T> {
List list = new List<T>();
void add(T value) {
this.list.add(value);
}
printInfo() {
print(this.list);
}
}
//可以动态的传入类型
void main() {
getData('tom');
getData<String>('jim');
getData<int>(12);
//List默认的就是泛型的类
List list = new List<String>();
list.add('jim');
print(list);
List list1 = new List<int>();
list1.add(123);
print(list1);
PrintClass p = new PrintClass();
p.add('1234');
p.add(123);
p.printInfo();
}
库
将一些公共的功能,单独抽离出来成一个文件,通过引入的方式进行使用的,就是一个库
自定义库
根据路径进行引入
系统内置的库
代码语言:javascript复制通过import ’dart:math‘
实例接口:https://news-at.zhihu.com/api/3/stories/latest
Pub包管理系统中的库(第三方库)
代码语言:javascript复制三个地址:htts://pub.dev/packages https://pub.flutter-io.cn/packages https://pub.dartlang.org/flutter/ 第一步:在项目中新建一个pubspec.yaml 将里面的name,desc,dep写好
name:'enlish',
description:'描述信息',
dependencies:'去地址里面的install中找安装的版本信息'
cd 到你的项目目录中,进行pub get命令进行安装第三方库 引入的时候import ’package:math‘ ‘看地址example中的教程就可以’
结尾
到此,Dart的基本介绍就结束了,Dart这门语言总体来说还是很容易接受的,毕竟学习的人一般不会java就会js,如果都会的话,就更加容易接受了,所以写的不是说很深入,只是简单的介绍一下,为学习flutter打下一些基础!