同步發表於筆者部落格

目的:

  • 為公司內部分享的筆記。
  • 寫給想由淺入深地了解 Dart 這個程式語言的人。

運算子(Operators)

四則運算、邏輯運算、程式運算等比較基礎的運算部份請參看官方文檔。
在此講一些比較特別的運算子

as, is, is!

// Type test operators
num n = 1.1;
print(n is! int);
print(n is double);
复制代码
true
true
复制代码

條件算符(Conditional expressions)

大部分程式語言都會有三元運算子 ?:,它可以很簡短的代替 if-else 語法。 Dart 中有幾個比較有趣的寫法 ???. 等。

???. 都會判斷左方的運算元是否為 null,再進行動作。

此範例若有些看不懂,可以看完下面一節 類別(上) 後再回頭看一次這裡。

class Account {String username;String password;Account({username, password}): this.username = username,// 下面兩種寫法是等價的// this.password = (password != null) ? password : 'AutomaticallyGenerateSecretPassword';this.password = password ?? 'AutomaticallyGenerateSecretPassword';@overrideString toString() {return "Account($username, $password)";}
}
复制代码
var a = Account(username: 'Bobson');
print(a);var b = Account();
b?.username = "I'm Groot";
print(b);
复制代码
Account(Bobson, AutomaticallyGenerateSecretPassword)
Account(I'm Groot, AutomaticallyGenerateSecretPassword)
复制代码

級聯符號(Cascade notation)

級聯符號可讓你針對一個物件進行一連串的函數操作,可省下寫重複變數的動作。

不用級聯符號的寫法:

var list = List()
list.insert(0, 123)
list.add(456)
list.addAll([789, 111]);
复制代码

用級聯符號的寫法:

var list = List()..insert(0, 123)..add(456)..addAll([789, 111]);
print(list);
复制代码
[123, 456, 789, 111]
复制代码

類別(Class) - 上篇

物件導向程式(OOP),是軟體程式設計中很重要的一環,打算用較長篇幅講解。

物件導向簡單說,從大到小;從整體應用(業務)邏輯到程式組件,都為他們繪製藍圖(也就是類別),
而電腦在執行程式時,會依照藍圖製造出成品(也就是物件實例),中間的製造過程統稱實例化

直接來看些 Dart 中 OOP 的應用吧。

// Point Class from dart:math
var p1 = Point(1, 2);
var p2 = Point(3, 4);
print("p1: $p1, p2: $p2");
print(p1.distanceTo(p2));
print(p2.magnitude);
复制代码
p1: Point(1, 2), p2: Point(3, 4)
2.8284271247461903
5.0
复制代码

Dart 中的 OOP 與其他 OOP 語言特性並無太多不同,
我找了 Dart 的數學函式庫 dart:math 中的 Point (二維平面上的點) 作為開篇。

class Point<T extends num> {final T x;final T y;const Point(T x, T y): this.x = x,this.y = y;String toString() => 'Point($x, $y)';.../*** Get the straight line (Euclidean) distance between the origin (0, 0) and* this point.*/double get magnitude => sqrt(x * x + y * y);/*** Returns the distance between `this` and [other].*/double distanceTo(Point<T> other) {var dx = x - other.x;var dy = y - other.y;return sqrt(dx * dx + dy * dy);}...
}
复制代码

類別通常都會包含幾個東西:

  • 屬性(property) 或 成員(member) - 物件會用到的變數
  • 建構子(constructor) - 可理解成創建(初始化)物件時會調用的函數
  • 方法(methods) - 物件會用到的函數

Point 對應來說:

  • 屬性或成員 -

    • final T x (此點的 x 座標)
    • final T y (此點的 y 座標)
  • 建構子 - const Point(T x, T y)...
  • 方法 -
    • String toString()... (print 時所顯示的字串),
    • double get magnitude... (此點與原點的距離),
    • double distanceTo(Point<T> other)... (此點與另一點的距離)

對應完之後是不是覺得很好理解了呢,這也是 OOP 的迷人之處。

接下來,我們試看看用 Dart 實現數學中複數(complex)的類別吧。

Complex Number (複數) - x + yi (i = √-1) 其中 x 及 y 皆為實數,分別稱為複數之「實部」和「虛部」。

class BaseComplex {num real;num imaginary;@overridebool operator ==(dynamic other) {if (other is! BaseComplex) {return false;} else {return real == other.real && imaginary == other.imaginary;}}@overrideString toString() => "BaseComplex($real, $imaginary)";
}
复制代码
  • 屬性或成員 -

    • num real (實部)
    • num imaginary (虛部)
  • 建構子 - 無
  • 方法 -
    • bool operator ==(dynamic other)... (複數物件相等函數)
    • String toString()... (print 時所顯示的字串),

稍稍分解一下,有兩項額外重點:

  • 建構子不寫的話會有一個預設的建構子可以調用,別忘了 Dart 中一次都繼承於 Object,所以實際上預設是調用了 Object 的建構子。
  • @override 這裝飾子是用來覆寫父類別的方法,Object 中包含了 ==()toString()

接著實際建造 BaseComplex 看看吧~

var c1 = BaseComplex();
c1.real = 5;
c1.imaginary = 2;
print(c1.runtimeType);var c2 = BaseComplex()..real = 5..imaginary = 2;
print("c1: $c1, c2: $c2");print(c1 == c2);
复制代码
BaseComplex
c1: BaseComplex(5, 2), c2: BaseComplex(5, 2)
true
复制代码
  • runtimeType 可顯示程式執行時,此變數的型別是什麼
  • print("c1: $c1, c2: $c2"); print 時會調用到物件的 toString 函數,若無覆寫 toString會顯示 Instance of 'BaseComplex'
  • c1 == c2 中實際上會調用我們覆寫的 == 函數。

稍微有些基礎建立類別方法了吧~
要多加一些特性在實際 Complex 物件囉。

class Complex {// Private property(member)num _real;num _imaginary;// Getters & Settersget real => _real;set real(num newReal) => _real = newReal;get imaginary => _imaginary;set imaginary(num newImaginary) => _imaginary = newImaginary;// Traditional way// Complex(num real, num imaginary) { //   this.real = real;  //   this.imaginary = imaginary;  // }// Syntactic sugarComplex(this._real, this._imaginary);// Named ConstructorComplex.real(num real) : this(real, 0);Complex.imaginary(num imaginary) : this(0, imaginary);@overridebool operator ==(dynamic other) {if (other is! Complex) {return false;} else {return real == other.real && imaginary == other.imaginary;}}@overrideString toString() {if (imaginary >= 0) {return "$real + ${imaginary}i";} else {return "$real - ${imaginary.abs()}i";}}
}
复制代码

這裡整理一下,加了哪些東西?

  • Private property(member) - (相當於 Java 裡的 private)

    • Dart 中的類別屬性(成員)前面加 _,可達到屬性被保護的作用。
    • 建造出來的物件 private 屬性無法直接透過 . 獲取。
  • Getters & Setters - (相當於 JavaBeans)
    • 屬於類別中的方法(methods),想要類別中的屬性有讀與寫的權限,可以讓屬性變 private,並寫個自定義的 Get 函數(讀)、Set 函數(寫)。
    • 但在物件操作上如此(都用自定義Get 函數和 Set 函數)會變得不方便,所以可直接使用 getset,在 Dart 中針對他們有對應的 keyword 可用。
  • 建構子
    • 傳統一般的建構子會用大括號來定義其初始的內容。
    • 在 Dart 中有更精簡的寫法(Syntactic sugar 語法糖)。
  • 命名建構子(Named Constructor)
    • 有時類別內會有特別常用的特定型態,可以額外寫成命名建構子。
    • 在 Flutter 中可以常常看到這種應用,如 ListView 中就有好幾個命名建構子 ListView.builderListView.seperatedListView.custom
  • 初始化列表(Initializer list)
    • 在建構子建構物件之前,可以用 : 來設定一些初始值。
    • 在 Flutter 源碼中可以常常看到這種應用。

你也可以瞧瞧...

參考

  • Dart 官方文檔 - Operators
  • Dart 官方文檔 - Classes
  • Introduction to Dart for Beginners - Intro to Classes and Objects - Part Three

系列文

  • Dart 基礎 - 4

Dart 基礎 - 3相关推荐

  1. Dart 基礎 - 4

    同步發表於筆者部落格 目的: 為公司內部分享的筆記. 寫給想由淺入深地了解 Dart 這個程式語言的人. 類別(Class) - 中篇 延續上一節的 類別(Class) - 上篇 方法(Methods ...

  2. mysql數據庫的增刪改查_MySQL數據庫之基礎增刪改查操作

    作者:        守望幸福 最后修改日期:2014-7-27 所操作的MySQL數據庫名:firstdb 所用的兩個表結構如下: student表 number name socre born_d ...

  3. Windows Phone 7.1 Sensor プログラミング基礎

    Windows Phone 7.1 Sensor プログラミング基礎 MSC D1-401セッションのフォローアップ第一弾です. この投稿では.Windows Phone 7.1 Mangoに搭載され ...

  4. stm32h7内存分配_【STM32H7教程】第25章 STM32H7的TCM,SRAM等五塊內存基礎知識

    第25章       STM32H7的TCM,SRAM等五塊內存基礎知識 本章教程為大家介紹STM32H7帶的ITCM,DTCM,AXI SRAM,SRAM1,SRAM2,SRAM3,SRAM4和備份 ...

  5. JS基礎:Hoisting 變量提升、TDZ 暫時性死區(Temporal Dead Zone)

    JS 基礎:Hoisting 變量提升.TDZ 暫時性死區(Temporal Dead Zone) 文章目錄 JS 基礎:Hoisting 變量提升.TDZ 暫時性死區(Temporal Dead Z ...

  6. 從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎

    "Talk is cheap. Show me the code." ― Linus Torvalds 老子第41章 上德若谷 大白若辱 大方無隅 大器晚成 大音希聲 大象無形 道 ...

  7. pytorch操作基礎(二)——基礎

    深度學習(二)--基礎 搭建好了pytorch後先不急着操作,先了解神經網絡是一件很重要的事情. pytorch基礎 -Tensor 即張量,表示多維的矩陣,pytorch裏面處理的單位就是一個個張量 ...

  8. 【繁中】Python 教學 爬蟲基礎

    Python 文章目录 Python __init__.__new__和__call__ 型態 len(資料) Tuple 特殊字串 成員運算子 input 集合Set 基本語法 Set 運算子 字典 ...

  9. JS基礎:Closure 閉包

    JS 基礎:Closure 閉包 文章目錄 JS 基礎:Closure 閉包 簡介 參考 正文 IIFE 立即執行函數(Immediately Invoked Functions Expression ...

最新文章

  1. python变量运算符_Python基础 — 变量和运算符
  2. 合成存储方法,局部/全局变量
  3. Android开发学习笔记-自定义组合控件
  4. LNMP与CA认证的童话故事
  5. 95-190-300-源码-window-Window Assigner
  6. 特斯拉蛇形充电机器人_特斯拉将内存设备锁入手套箱内 确保哨兵模式/TeslaCam数据安全...
  7. Autograd看这一篇就够了!
  8. 【Oracle】ORA-30042: Cannot offline the undo tablespace
  9. UVA10738 Riemann vs Mertens【欧拉筛法】
  10. 【转】程序员的十种级别
  11. RHEL 5基础篇—管理系统计划任务
  12. [16]manjaro安装nvidia驱动
  13. 免安装版VSCode配置(便携模式)
  14. 表示微型计算机系统稳定性,计算机选择题
  15. 使用VIA(VCC)制作coco数据集
  16. 圆瓶、扁瓶、三色瓶砖、数百品牌分选,弓叶科技的分选神技
  17. linux centos服务器安全初级防御
  18. 浅谈模块化UPS对提高数据中心适应性的作用
  19. Documents最新版 2021版本 下载试用
  20. 基于ssm高校共享单车管理系统 (源代码+数据库) 604

热门文章

  1. java绝对路径和相对路径_Java文件路径,绝对路径和规范路径
  2. scala中命名参数函数_Scala中的命名参数和默认参数值
  3. scala案例_Scala案例类和案例对象深入(第2部分)
  4. 十分钟快速上手结巴分词
  5. 30. Substring with Concatenation of All Words
  6. shell学习笔记二
  7. mysql “Access denied for user 'root'@'localhost'
  8. 【大数相乘】LeetCode 43. Multiply Strings
  9. 【归并排序+递归】LeetCode 148. Sort List
  10. 【难题+重点】剑指offer——面试题40:数组中只出现一次的数字