淘先锋技术网

首页 1 2 3 4 5 6 7

【Dart】006-类的定义和使用

在编程中, 的目的是组织 数据功能 ,起到封装的作用,提供解决某类特定问题的方案,或方案中的某一环节。

一、类的定义

1、概述

类通过 class 关键字进行定义,其后单词表示 类的名称 。名称之后,通过 {} 表示类定义的作用域,在其中定义类的 成员变量成员方法

class ${className}{
	// 类体
}

2、简单定义与实例化

代码示例

void main(List<String> arguments) {
  // 实例化对象
  Student student = Student('张三', 18);
  // 访问成员变量
  print(student.name);
  print(student.age);
  // 修改成员变量
  student.name = '李四';
  student.age = 20;
  // 再次访问成员变量
  print(student.name);
  print(student.age);
}

/// 学生类
class Student {
  /// 名字
  String name;

  /// 年龄
  int age;

  Student(this.name, this.age);
}

运行结果

张三
18
李四
20

3、成员方法

代码示例

void main(List<String> arguments) {
  // 实例化对象
  Student student = Student('张三', 18);
  // 调用成员方法,获取学生的基本信息描述
  String info = student.getStudentInfo();
  // 打印信息
  print(info);
}

/// 学生类
class Student {
  /// 名字
  String name;

  /// 年龄
  int age;

  Student(this.name, this.age);

  /// 获取学生的基本信息描述
  String getStudentInfo() {
    return '姓名:${this.name},年龄:${this.age}';
  }
}

运行结果

姓名:张三,年龄:18

箭头函数写法

/// 获取学生的基本信息描述
String getStudentInfo() => '姓名:${this.name},年龄:${this.age}';

4、get 与 set 关键字

概述

getset 关键字修饰的是 成员方法 ,其实本质上来说它们只是一种简写方式,常用于对 成员变量 的维护。它只不过是个语法糖而言,本质上仍是方法。

代码示例

void main(List<String> arguments) {
  // 实例化对象
  Student student = Student('张三', 18);
  // getName
  print(student.getName);
  // setName
  student.setName = '李四';
  print(student.getName);
  // getStudentInfo
  print(student.getStudentInfo);
}

/// 学生类
class Student {
  /// 名字
  String name;

  /// 年龄
  int age;

  Student(this.name, this.age);

  /// 获取名字的get方法
  String get getName => name;

  /// 设置名字的set方法
  set setName (String name) => this.name = name;

  /// 获取学生基本信息
  String get getStudentInfo => '姓名:$name,年龄:$age';
}

运行结果

张三
李四
姓名:李四,年龄:18

二、类的构造方法

1、特点

构造方法作为一种特殊的函数,在定义上有一些独有的特点:

  • 【1】构造方法在声明时无 返回值
  • 【2】构造方法 可以 没有方法体。
  • 【3】在参数列表中可以通过 this.成员 ,可以为成员变量进行赋值。

2、完整版的构造方法

简化版

完整版

Student(String name, int age)
    : this.name = name,
	this.age = age;

3、使用命名参数

4、命名构造

一个类多个构造!

/// 学生类
class Student {
  /// 名字
  String name;

  /// 年龄
  int age;

  /// 默认对象
  Student.defaultObj(): name = "訾博", age = 27;

  /// 二倍年龄
  Student.doubleAge(this.name, int age): age = age * 2;
}

三、类中的不可变成员与静态成员

1、不可变成员

在前面介绍量的定义时,我们知道 final 关键字修饰的成员只能被赋值一次。如果类的一个成员变量使用 final 进行修饰,就表示这个成员不允许进行修改。

代码示例

void main(List<String> arguments) {
  // 实例化对象
  Student student = Student('张三', 18);
  student.name = "訾博";
}

/// 学生类
class Student {
  /// 名字
  final String name;

  /// 年龄
  final int age;
  
  Student(this.name, this.age);
}

报错

image-20230716160421859

2、静态成员

静态成员由 本身直接访问,不依附于 对象

代码示例

void main(List<String> arguments) {
  print(Student.name);
}

/// 学生类
class Student {
  /// 名字
  static String name = "訾博";
}

运行结果

訾博

3、静态方法

static也可以修饰类的成员方法,称为静态方法

代码示例

void main(List<String> arguments) {
  Student.printName("訾博");
}

/// 学生类
class Student {
  /// 打印名字
  static printName(String name) => print(name);
}

运行结果

訾博

四、成员和类的可见性

在Dart中,成员和类可以具有不同的可见性,这由一些访问修饰符控制。这些修饰符确定了在代码中的哪些位置可以访问类或成员。

Dart中有四种可见性修饰符:

  1. public:默认的可见性修饰符。如果没有显式指定修饰符,类和成员默认为公共的。公共成员可以在任何位置被访问。

  2. private:使用下划线 _ 开头的标识符被视为私有的。私有成员只能在同一个库(文件)中被访问,无法从库的外部访问。

    class MyClass {
      String _privateField;
    
      void _privateMethod() {
        // 私有方法的实现
      }
    }
    
    
  3. protected:在Dart中没有直接的 protected 关键字,但可以通过约定来模拟 protected 成员。使用下划线 _ 开头的标识符被视为库内部的私有成员,但可以被子类访问。

    class MyBaseClass {
      String _protectedField;
    
      void _protectedMethod() {
        // 受保护方法的实现
      }
    }
    
    class MyDerivedClass extends MyBaseClass {
      void accessProtectedMember() {
        _protectedField = 'Value'; // 可以在子类中访问受保护字段
        _protectedMethod(); // 可以在子类中调用受保护方法
      }
    }
    
  4. package-private:在Dart中没有直接的 package-private 关键字,但可以通过约定来模拟。如果在定义类或成员时不使用任何可见性修饰符,它将具有包级私有性。包级私有成员只能在同一个包中被访问。

    class _PackagePrivateClass {
      // 包级私有类
    }
    
    void _packagePrivateFunction() {
      // 包级私有函数
    }