由于想要写一款性能较好,但是又可以一套代码多个平台运行的客户端app,所以选择了flutter 就去看了官方文档,大体发现flutter使用的dart语言和java和js差不多,感觉就是缝合怪。
Dart 是一种面向对象的编程语言,语法上与 Java、JavaScript 等语言有一些相似之处,因此对于有 Java 基础的开发者,Dart 的语法应该相对容易理解。以下是 Dart 语言的语法介绍,特别对比了与 Java 的异同。
看完由遗忘很正常 ,必要时可以查看官方中文文档
https://dart.cn/language/
1. 基本语法
1.1 变量声明
Dart 是强类型语言,但可以通过 var
来声明类型推断的变量。
- Dart:
int age = 30; // 明确类型
var name = 'John'; // 自动推断为 String
- Java:
int age = 30; // 明确类型
String name = "John"; // 明确类型
Dart 中 var
类似于 Java 的局部类型推断 var
(自 Java 10 引入)。
1.2 常量
Dart 中使用 const
和 final
来声明常量。const
是编译时常量,而 final
是运行时常量,赋值后不能修改。
- Dart:
const double pi = 3.14; // 编译时常量
final currentTime = DateTime.now(); // 运行时常量
- Java:
final double PI = 3.14; // Java 没有 const,但 final 可以限制变量不可修改
如果不显示定义 编译时会自动推断
var b="奥萨苏";
1.3 函数定义
Dart 中的函数定义与 Java 类似,但 Dart 的函数可以是顶级函数,不需要类的包装。
- Dart:
int add(int a, int b) {
return a + b;
}
// 简写方式(箭头函数)
int subtract(int a, int b) => a - b;
- Java:
public int add(int a, int b) {
return a + b;
}
Dart 的函数可以直接返回表达式,使用 =>
箭头函数表示法。
如果不显示定义返回值 则是dynamic类型
void main() {
int a=12 ;
print('你好世界');
print(a++);
String name ="jack";
print("开发者的名字是=$name"); //输出的时候的引用
// 双引号嵌套单引号
// 单引号嵌套双引号
print("他就是世界第一的'火影大王'");
print('他就是世界第一的"火影大王"');
var b="奥萨苏";
print(b);
add(1,2);
}
add (int a,int b){
return a+b;
}
2. 控制流
2.1 条件语句
Dart 的 if-else
语法与 Java 完全一致。
- Dart:
if (age > 18) {
print('Adult');
} else {
print('Minor');
}
- Java:
if (age > 18) {
System.out.println("Adult");
} else {
System.out.println("Minor");
}
2.2 循环
Dart 的循环控制结构与 Java 非常相似,for
、while
、do-while
循环的语法基本一致。
- Dart:
for (int i = 0; i < 5; i++) {
print(i);
}
int i = 0;
while (i < 5) {
print(i);
i++;
}
- Java:
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
int i = 0;
while (i < 5) {
System.out.println(i);
i++;
}
2.3 switch-case
Dart 的 switch-case
语法与 Java 类似,但 case
不需要 break
,也没有 fall-through
行为。
- Dart:
var grade = 'A';
switch (grade) {
case 'A':
print('Excellent');
break;
case 'B':
print('Good');
break;
default:
print('Unknown grade');
}
- Java:
char grade = 'A';
switch (grade) {
case 'A':
System.out.println("Excellent");
break;
case 'B':
System.out.println("Good");
break;
default:
System.out.println("Unknown grade");
}
3. 面向对象编程
3.1 类和对象
Dart 是面向对象语言,所有东西都是对象,类的定义方式与 Java 类似。
- Dart:
class Person {
String name;
int age;
// 构造函数
Person(this.name, this.age);
void greet() {
print('Hello, my name is $name');
}
}
void main() {
var person = Person('Alice', 30);
person.greet();
}
- Java:
class Person {
String name;
int age;
// 构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void greet() {
System.out.println("Hello, my name is " + name);
}
}
public static void main(String[] args) {
Person person = new Person("Alice", 30);
person.greet();
}
3.2 继承
Dart 支持单继承,使用 extends
关键字。
- Dart:
class Employee extends Person {
String jobTitle;
Employee(String name, int age, this.jobTitle) : super(name, age);
@override
void greet() {
print('Hello, I am $name, and I work as a $jobTitle');
}
}
- Java:
class Employee extends Person {
String jobTitle;
public Employee(String name, int age, String jobTitle) {
super(name, age);
this.jobTitle = jobTitle;
}
@Override
public void greet() {
System.out.println("Hello, I am " + name + ", and I work as a " + jobTitle);
}
}
mix 可以实现类似多继承的效果
虽然
3.3 接口和抽象类
Dart 不需要显式的 interface
关键字,但所有类都可以作为接口被实现。使用 abstract
关键字定义抽象类。
- Dart:
abstract class Animal {
late String name;
Animal(this.name); // 抽象方法
void sound(); // 抽象方法
}
//作为接口被实现
class Dog extends Animal{
Dog(String name):super(name);
@override
void sound() {
print('Woof');
}
}
abstract interface class Animal1 {
late String name;
Animal1(this.name); // 抽象方法
void sound();
}
//使用接口被实现 但是无法给父类的属性赋值
class Dog1 implements Animal1{
Dog1(String name):super(name);
@override
void sound() {
print('Woof');
}
@override
String name;
}
- Java:
abstract class Animal {
abstract void sound();
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Woof");
}
}
演示代码
这里dart 利用的是重写来实现继承和实现的逻辑
class Person {
String name;
int age;
// 构造函数
Person(this.name, this.age);
void greet() {
print('Hello, my name is $name');
}
}
void main() {
// 多态 父类对象 申明位子类对象
Person person = Employee('网名', 30,"日报记者");
person.greet();
Iservice service=ServiceImple("jack");
service.sayhello();
}
class Employee extends Person {
String jobTitle;
//调用父类的构造函数 和本类的构造函数
Employee(String name, int age, this.jobTitle) : super(name, age);
@override
void greet() {
print('Hello, I am $name, and I work as a $jobTitle');
}
}
abstract class Iservice {
late String name; // 抽象类中的变量
Iservice(this.name);
void sayhello(){
print("接口说你好");
}
int Add(int a, int b);
}
class ServiceImple extends Iservice {
ServiceImple(String name):super(name);
/**
* 实现父类空方法
*/
@override
int Add(int a, int b) {
return a + b; // 实现加法
}
/**
* 对父类重写 增强
*/
@override
void sayhello() {
super.sayhello();
print('Hello, my name is $name'); // 使用 name
}
}
4. 异步编程
4.1 异步函数
Dart 有内置的 async
和 await
关键字,用于处理异步编程,这与 JavaScript 中的异步编程类似。(缝合怪)
Dart:
感觉跟js的很想
Future<void> fetchData() async {
var data = await fetchFromServer();
print(data);
}
Future<String> fetchFromServer() {
// 模拟从服务器获取数据 俩秒后返回数据
return Future.delayed(Duration(seconds: 2), () => 'Server data');
}
//冒泡排序
main() {
fetchData();
}
- Java 中没有
async
和await
,你可以通过CompletableFuture
或其他异步库实现异步操作:
import java.util.concurrent.CompletableFuture;
public class AsyncExample {
public static void main(String[] args) {
fetchData();
}
public static void fetchData() {
CompletableFuture.supplyAsync(() -> fetchFromServer())
.thenAccept(data -> System.out.println(data));
}
public static String fetchFromServer() {
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Server data";
}
}
4.2 Stream
Dart 中的 Stream
类似于 Java 的 Stream
,但它更侧重于处理异步事件流。
- Dart:
Stream<int> countStream(int to) async* {
for (int i = 1; i <= to; i++) {
yield i;
}
}
void main() async {
await for (var value in countStream(5)) {
print(value); // 依次输出 1 到 5
}
}
- Java 中的
Stream
主要用于集合的函数式操作,而异步流处理可以使用RxJava
或Project Reactor
。
5. 其他重要特性
5.1 集合操作
Dart 中的集合与 Java 类似,包括 List
、Set
、Map
等。
api和java差不多
- Dart:
List<int> numbers = [1, 2, 3];
//java 可不能这样
Map<String, int> ages = {'Alice': 30, 'Bob': 25};
numbers.forEach(print);
- Java:
List<Integer> numbers = Arrays.asList(1, 2, 3);
Map<String, Integer> ages = new HashMap<>();
ages.put("Alice", 30);
ages.put("Bob", 25);
numbers.forEach(System.out::println);
Dart 语言中的集合操作非常丰富,类似于 Java 的集合框架,但也有其独特之处。Dart 提供了常用的集合类型(如 List
、Set
和 Map
),并提供了大量的 API 来操作集合。以下是 Dart 集合操作和 API 的详解:
1. List(列表)
List
是 Dart 中的可变数组,类似于 Java 中的 ArrayList
。它可以存储有序的元素,并且允许重复元素。
创建列表
空列表:
var list = <int>[]; // 创建空的整数列表
带初始值的列表:
var list = [1, 2, 3, 4]; // 初始化列表
不可变列表:
var fixedList = List.unmodifiable([1, 2, 3]); // 创建不可修改的列表
常用 API
添加元素:
list.add(5); // 添加单个元素 list.addAll([6, 7]); // 添加多个元素
插入元素:
list.insert(0, 0); // 在索引 0 处插入 0 list.insertAll(1, [8, 9]); // 在索引 1 处插入多个元素
删除元素:
list.remove(1); // 删除第一个值为 1 的元素 list.removeAt(0); // 删除索引为 0 的元素 list.removeWhere((item) => item % 2 == 0); // 删除所有符合条件的元素
查找元素:
var containsTwo = list.contains(2); // 检查列表是否包含某个元素 var indexOfThree = list.indexOf(3); // 查找元素的位置
排序:
list.sort(); // 升序排序 list.sort((a, b) => b.compareTo(a)); // 降序排序
遍历:
list.forEach((item) => print(item)); // 遍历列表并打印每个元素
映射和过滤:
var squaredList = list.map((item) => item * item).toList(); // 对每个元素平方并返回新列表 var evenList = list.where((item) => item.isEven).toList(); // 筛选偶数
其他常用操作:
list.clear(); // 清空列表 var isEmpty = list.isEmpty; // 检查是否为空 var length = list.length; // 获取长度
2. Set(集合)
Set
是一个无序且元素唯一的集合,类似于 Java 的 HashSet
。
创建集合
空集合:
var set = <int>{}; // 创建空的整数集合
带初始值的集合:
var set = {1, 2, 3, 4}; // 初始化集合
常用 API
添加元素:
set.add(5); // 添加单个元素 set.addAll([6, 7]); // 添加多个元素
删除元素:
set.remove(1); // 删除元素 1 set.removeWhere((item) => item.isEven); // 删除符合条件的元素
集合操作:
var unionSet = set.union({5, 6}); // 并集 var intersectionSet = set.intersection({3, 4, 5}); // 交集 var differenceSet = set.difference({3, 4}); // 差集
遍历:
set.forEach((item) => print(item)); // 遍历集合
其他常用操作:
var containsThree = set.contains(3); // 检查集合是否包含某个元素 var isEmpty = set.isEmpty; // 检查是否为空 var length = set.length; // 获取长度
3. Map(映射)
Map
是键值对的集合,类似于 Java 的 HashMap
。键必须是唯一的,值可以重复。
创建映射
空映射:
var map = <String, int>{}; // 创建空的键值对映射
带初始值的映射:
var map = {'one': 1, 'two': 2}; // 初始化映射
常用 API
添加或更新键值对:
map['three'] = 3; // 添加新键值对 map.update('two', (value) => value + 2); // 更新键 'two' 的值
删除键值对:
map.remove('one'); // 删除键 'one' 对应的键值对
查找值:
var value = map['two']; // 根据键获取值 var containsKey = map.containsKey('two'); // 检查是否包含某个键 var containsValue = map.containsValue(2); // 检查是否包含某个值
遍历:
map.forEach((key, value) => print('$key: $value')); // 遍历映射
获取键或值的集合:
var keys = map.keys; // 获取所有键 var values = map.values; // 获取所有值
其他常用操作:
var isEmpty = map.isEmpty; // 检查是否为空 var length = map.length; // 获取长度
5.2 异常处理
Dart 的异常处理与 Java 类似,使用 try-catch
。
- Dart:
try {
var result = 10 ~/ 0; // 整数除法会抛出异常
} catch (e) {
print('Caught an exception: $e');
} finally {
print('This will always execute');
}
- Java:
try {
int result = 10 / 0;
} catch (ArithmeticException e) {
System.out.println("Caught an exception: " + e);
} finally {
System.out.println("This will always execute");
}
5.3 空安全
Dart 支持空安全(null-safety),防止 null
引发错误,类似于 Java 的 Optional。
- Dart:
String? name; // 允许为 null
name = null;
print(name?.length); // 使用 ?. 操作符避免空指针异常
- Java:
Optional<String> name = Optional.ofNullable(null);
System.out.println(name.map(String::length).orElse(0));
枚举
dart 的枚举也和java类似
dart 需要强制编译时就申明构造函数不可变
enum HttpStatus {
ok(200, "响应成功"),
created(201, "创建成功"),
badRequest(400, "请求错误"),
unauthorized(401, "未授权"),
notFound(404, "未找到"),
internalServerError(500, "服务器内部错误");
final int code;
final String name;
//一申明即不可变
const HttpStatus(this.code, this.name);
}
java
public enum Test {
ok(200, "OK");
final int code;
final String message;
Test(int code, String message) {
this.code = code;
this.message = message;
}
}
补充
下面的内容都是用到啥 补充啥
初始化
构造函数后面跟 :代码块即可执行初始化 在构造函数之前执行
还有之前的构造函数调用父类方式本质也只是这种初始化的缩写
class Animal{
String name;
int age;
Animal(this.name,this.age);
}
class Person extends Animal{
String action;
Person(String name,int age,this.action):super(name,age){
print("构造函数被调用");
super.age=age;
super.name=name;
}
}
可变参数搭配可空操作
void greet(String name, {String? greeting, String? farewell}) {
if (greeting != null) {
print('$greeting, $name!');
} else {
print('Hello, $name!');
}
if (farewell != null) {
print('$farewell, $name!');
}
}
void main() {
greet('Alice'); // 输出: Hello, Alice!
greet('Bob', greeting: 'Hi'); // 输出: Hi, Bob!
greet('Charlie', farewell: 'Goodbye'); // 输出: Hello, Charlie! Goodbye, Charlie!
greet('David', greeting: 'Hey', farewell: 'See you'); // 输出: Hey, David! See you, David!
}
文件操作
在 Dart 中,文件操作通常使用 dart:io
库来进行,包括读取、写入、复制、删除文件等操作。以下是一些常见的文件操作示例:
1. 引入 dart:io
首先要引入 dart:io
,这个库提供了对文件系统的访问。
import 'dart:io';
2. 读取文件
Dart 提供多种方式读取文件内容,包括同步和异步方式:
异步读取文件内容
使用 readAsString()
方法以异步方式读取文件内容为字符串:
import 'dart:io';
void main() async {
File file = File('example.txt');
try {
// 读取文件内容为字符串
String contents = await file.readAsString();
print('文件内容: $contents');
} catch (e) {
print('文件读取失败: $e');
}
}
异步读取二进制文件
可以使用 readAsBytes()
读取文件的字节内容:
import 'dart:io';
void main() async {
File file = File('example.txt');
try {
// 读取文件内容为字节
List<int> bytes = await file.readAsBytes();
print('文件字节: $bytes');
} catch (e) {
print('文件读取失败: $e');
}
}
同步读取文件内容
使用 readAsStringSync()
进行同步读取(注意:同步操作会阻塞程序执行,适用于简单任务):
import 'dart:io';
void main() {
File file = File('example.txt');
try {
// 同步读取文件内容为字符串
String contents = file.readAsStringSync();
print('文件内容: $contents');
} catch (e) {
print('文件读取失败: $e');
}
}
3. 写入文件
Dart 提供了多种方式将内容写入文件,支持字符串和字节写入操作。
异步写入文件
使用 writeAsString()
异步写入字符串到文件:
import 'dart:io';
void main() async {
File file = File('output.txt');
try {
// 异步写入字符串到文件
await file.writeAsString('这是一些文件内容');
print('文件写入成功');
} catch (e) {
print('文件写入失败: $e');
}
}
同步写入文件
使用 writeAsStringSync()
同步写入文件:
import 'dart:io';
void main() {
File file = File('output.txt');
try {
// 同步写入字符串到文件
file.writeAsStringSync('这是同步写入的文件内容');
print('文件写入成功');
} catch (e) {
print('文件写入失败: $e');
}
}
4. 追加文件内容
使用 writeAsString()
和 writeAsStringSync()
的 mode
参数,可以向文件中追加内容。
异步追加内容
import 'dart:io';
void main() async {
File file = File('output.txt');
try {
// 异步追加内容到文件
await file.writeAsString('追加的内容', mode: FileMode.append);
print('文件追加成功');
} catch (e) {
print('文件追加失败: $e');
}
}
同步追加内容
import 'dart:io';
void main() {
File file = File('output.txt');
try {
// 同步追加内容到文件
file.writeAsStringSync('同步追加的内容', mode: FileMode.append);
print('文件追加成功');
} catch (e) {
print('文件追加失败: $e');
}
}
5. 删除文件
要删除文件,可以使用 delete()
或 deleteSync()
。
异步删除文件
import 'dart:io';
void main() async {
File file = File('output.txt');
try {
// 异步删除文件
await file.delete();
print('文件删除成功');
} catch (e) {
print('文件删除失败: $e');
}
}
同步删除文件
import 'dart:io';
void main() {
File file = File('output.txt');
try {
// 同步删除文件
file.deleteSync();
print('文件删除成功');
} catch (e) {
print('文件删除失败: $e');
}
}
6. 检查文件是否存在
在操作文件之前,可以先检查文件是否存在:
import 'dart:io';
void main() async {
File file = File('example.txt');
if (await file.exists()) {
print('文件存在');
} else {
print('文件不存在');
}
}
7. 复制文件
可以使用 copy()
或 copySync()
方法来复制文件:
异步复制文件
import 'dart:io';
void main() async {
File file = File('example.txt');
try {
// 异步复制文件
await file.copy('example_copy.txt');
print('文件复制成功');
} catch (e) {
print('文件复制失败: $e');
}
}
同步复制文件
import 'dart:io';
void main() {
File file = File('example.txt');
try {
// 同步复制文件
file.copySync('example_copy.txt');
print('文件复制成功');
} catch (e) {
print('文件复制失败: $e');
}
}
8. 列出目录中的文件
Dart 提供 Directory
类来操作目录,使用 list()
列出目录中的文件和子目录:
import 'dart:io';
void main() async {
Directory dir = Directory.current; // 当前目录
try {
await for (var entity in dir.list()) {
print(entity.path);
}
} catch (e) {
print('读取目录失败: $e');
}
}
权限控制
在 Dart 中,确实不像 Java 那样有显式的权限修饰符(如 public
、private
、protected
和 default
),但 Dart 提供了其他机制来实现类似的权限控制,主要是通过命名约定和库系统来控制访问权限。
1. 私有成员的命名约定
在 Dart 中,私有属性和方法通过命名约定来实现。你可以通过在成员名称前加下划线 _
来表示该成员是私有的(private),只能在同一个库中访问。
例子:
class Example {
// 私有属性
String _privateVariable = 'This is private';
// 私有方法
void _privateMethod() {
print('This is a private method');
}
// 公有方法
void publicMethod() {
print('This is a public method');
}
}
void main() {
var example = Example();
// 可以访问公有方法
example.publicMethod();
// 无法访问私有方法和属性,会导致编译错误
// example._privateVariable; // 错误:'_privateVariable' 不可访问
// example._privateMethod(); // 错误:'_privateMethod' 不可访问
}
在上面的例子中,属性 _privateVariable
和方法 _privateMethod
是私有的,只能在 Example
类内部或同一 Dart 库中访问,外部代码无法访问。
2. 库(Library)系统的权限控制
Dart 使用库系统来进行更高级别的权限控制。默认情况下,Dart 中的每个文件都是一个库。如果某个类、方法、属性是私有的(以 _
开头),它只能在当前库中访问,其他库(通常是其他文件)无法访问它。
例子:
- lib/a.dart
class A {
String _privateInA = 'Private in A';
String publicInA = 'Public in A';
}
- lib/b.dart
import 'a.dart';
void main() {
var a = A();
// 可以访问公有属性
print(a.publicInA);
// 无法访问私有属性
// print(a._privateInA); // 错误:'_privateInA' 不可访问
}
在这个例子中,_privateInA
是 A
类中的私有属性,只能在 a.dart
中访问。在 b.dart
中尝试访问该属性会导致编译错误。
3. Dart 没有 protected
的概念
Dart 没有类似 Java 的 protected
关键字,因此 Dart 没有直接支持子类或同包中的类访问受保护成员的机制。
不过,在 Dart 中可以通过合理设计类结构和通过公有 API 暴露必要功能来实现类似的权限控制。例如,你可以使用接口或抽象类来控制类的可见性和继承行为。
4. Dart 中的 getter 和 setter 控制
Dart 中可以通过 getter
和 setter
方法来控制属性的访问。例如,你可以让某个属性只读或只写。
例子:
class Person {
String _name;
// 构造函数
Person(this._name);
// 只读属性
String get name => _name;
// 设置方法是私有的,因此无法从外部设置
void _setName(String newName) {
_name = newName;
}
}
void main() {
var person = Person('John');
// 可以获取名字
print(person.name);
// 无法设置名字
// person._setName('Doe'); // 错误:'_setName' 不可访问
}
在这个例子中,_name
属性是私有的,但可以通过公有的 get
方法访问。设置方法 _setName
是私有的,外部代码不能直接修改 name
。