主頁 > 後端開發 > Dart語言學習(十二) Dart面向物件

Dart語言學習(十二) Dart面向物件

2020-10-10 05:23:18 後端開發

Dart作為一種高級語言,支持面向物件的很多特性,并且支持基于mixin的繼承方式,

基于mixin的繼承方式是指:一個類可以繼承自多個父類,相當于其他語言里的多繼承,

所有的類都有同一個基類Object,這和特性類似于Java、Objective-C 等語言,Java所有的類也都是繼承自Object,也就是說一切皆物件,

 

//實體化了一個User類的物件user
var user = new User('Liming',25);
  • 實體化成員變數

Class User{
    String name;//name 成員變數
    int age;//age 成員變數
}

類定義中所有的變數都會隱式的定義setter方法,針對非空的變數會額外增加getter方法,

實體化成員變數請參考如下代碼:

void main(){
    var user = new User();
    user.name = 'Liming';//相當于使用了name的setter方法
    user.age = 25;
}
  • 建構式

  1.常規的建構式

建構式是用來構造當前類的函式,是一種特殊的函式,函式名稱必須要和類名相同才行.

如下代碼為User類添加了一個建構式,函式里給User類的兩個成員變數初始化了值:

Class User{
    String name;
    int age;
    User(String mName,int mAge){
        this.name = mAge;
        this.age = mAge;
    }
}

this關鍵字指向了當前類的實體

上面的代碼可以簡化為:

Class User{
    String name;
    int age;
    User(this.name,this.age);
}

第一種沒有簡化的構造方法初始化成員變數是在方法體內進行初始化的,

第二種簡化的構造方法初始化成員變數,是在實體化類的時候直接進行賦值初始化的,

  2.命名的建構式

使用命名建構式是 從另一類或現有的資料中快速實作建構式 ,代碼如下所示:

Class User{
    String name;
    int age;
    //普通建構式
    User(this.name,this.age);

    //命名建構式
    User.fromJson(Map json){
        name = json['name'];
        age = json['age'];
    }
}

//在實體化類的時候,如果沒有傳參,會默認呼叫無引數的構造方法
//普通建構式
var user = new User('張三',25);

//命名建構式
var user = new User.fromJson(mMapJson);

 

  3.子類的創建

注1:子類在繼承父類的時候,如果在父類中有顯示的提供一個無名、無參的建構式,不會繼承父類無名有參建構式和命名建構式,即:子類只會繼承父類無名無參的建構式,(程式會給類隱式的生成一個無名、無參的建構式)

注2:子類在繼承父類的時候,如果在父類中沒有有顯示的提供一個無名、無參的建構式,子類必須手動呼叫父類的一個建構式,在這種情況下,呼叫的父類的建構式要放在子類建構式之后,在子類建構式體之前,用“:”分隔,

注3:父類的建構式會在子類的建構式前呼叫,

注4:默認情況下,子類只能呼叫父類無名、無引數的建構式,

注1和注3:父類中有一個無名、無參的建構式,子類繼承父類,會默認繼承父類無名、無參的建構式(即使有其他無名、有參的建構式或者命名建構式,子類都不會呼叫),并且,父類的無名、無參的建構式會在子類的建構式之前被呼叫,

Class Futher {

    //無名、無參的建構式
    Futher(){
        print('我是父類無名、無參的建構式');
    }
}

Class Son extends Futher {
    //因為父類有顯式的宣告一個無名、無參的建構式,所以不用手動呼叫父類的建構式,
    Son.fromJson(Map mMapJson){
        print('我是子類的命名建構式');
    }
}

var son = new Son.fromJson(mMapJson);
//列印結果
//我是父類無名、無參的建構式
//我是子類的命名構造函

注2:下面代碼里,子類的命名構造方法寫了兩種方式,第一種是正確的,第二種是錯誤的,有詳細的注釋, 如果有疑問請留言,

Class Futher {

    //無名、無參的建構式
    Futher.printSth(){
        print('我是父類無名、無參的建構式');
    }
}

Class Son extends Futher {
    //因為父類沒有有顯式的宣告一個無名、無參的建構式,所以需要手動的呼叫父類的建構式,
    Son.fromJson(Map mMapJson) : super Futher.printSth{
        print('我是子類的命名建構式');
    }

    //這種寫法會報錯,因為父類中沒有顯示的提供一個無名、無參的建構式,所以需要像上面那樣,手動呼叫父類的一個建構式
    Son.fromJson(Map mMapJson){
        print('我是子類的命名建構式');
    }
}

  4.建構式初始化串列

上面在講解常規的建構式和命名建構式的時候,示例代碼都有對類中的成員變數進行了初始化,

特點是在建構式的方法體內進行初始化,初始化成員變數還有另一種方式,就是在建構式運行前來初始化成員變數,

Class User {
    String name;
    int age;

    User(mName,mAge)
        :name = mName,
        age = mAge{
            // Do Some Thing
        }
}

特點是在建構式的方法體前(大括號前面)來初始化成員變數,變數間用“,”分隔,

  • 讀取和寫入物件

get()和set()方法是專門用于讀取和寫入物件的屬性的方法,每一個類的實體,系統都會隱式的包含有get()和set()方法,

例如,定義一個矩形的類,有上、下、左、右:top、bottom、left、right四個成員變數,使用get及set關鍵字分別對right、bottom進行獲取和設定值,代碼如下所示:

Class Rectangle {
    num left;
    num top;
    num width;
    num height;

    Rectangle(this.left,this.top,this.width,this.height);

    num get right => left + width;//獲取righht的值(第一行)

    set right(num value) => left = value - width;//設定right的值,同時left也發生了變化(第二行)

    num get bottom => top + height;//獲取bottom的值(第三行)

    set bottom(num value) => top = value - height;//設定bottom值,同時top也發生了變化(第四行)
}

void main(){
    var rect = new Rectangle(3,4,20,15);//實體化Rectangle,并給類中的4個變數進行初始化賦值

    print('left:'+rect.left.toString());//獲取left的值,并列印 left = 3
    print('right:'+rect.right.toString());//獲取right的值,并列印,這里執行了Rectangle類中第一行代碼,right = left + width,right = 3+20 = 23
    rect.right = 30;//重新給right進行賦值 right = 30,這里執行了Rectabgke類中的第二行代碼,將right的值設定為30,并且,將left的值改為30 - 20,left = 30-20 = 10
    print('right的值改為30');
    print('left:'+rect.left.toString());//獲取left的值,并列印,因為上面給right重新賦值的時候,也改變了left的值,所以,此時left = 10
    print('right:'+rect.right.toString());//rect.right = 30將right的值改為了30,所以,right = 30


    print('top:'+rect.top.toString());
    print('bottom:'+rect.bottom.toString());
    rect.bottom = 50;
    print('bottom的值改為50');
    print('top:'+rect.top.toString());
    print('bottom:'+rect.bottom.toString());
}

//列印結果
left:3
right:23
right的值改為30
left:10
right:30
top:4
bottom:19
bottom的值改為50
top:35
bottom:50

上面的示例注釋已經解釋的很清楚了,如果有任何疑問,請留言!!!

這里我就解釋一下“=>”的作用,在Dart里面,大家可以簡單的理解為接下來要繼續執行后面的操作,

  • 重運算子載操作

在講解多載運算子前需要先說明Dart里面的一個關鍵字operator,operator和運算子一起使用,表示一個運算子多載函式,在理解時可以將operator和運算子(如operator+或operator-)視為一個函式名,撰寫一個例子方便理解,

Class Vector {
    final int x;
    final int y;
    const Vector(this.x,this.y);

    //多載加號 + (a+b)
    Vector operator + (Vector v){
        return new Vector(x + v.x,y + v.y);
    }
}

void main() {
    //實體化兩個變數
    final result1 = new Vector(10,20);
    final result2 = new Vector(30,40);

    final result = result1 + result2;

    print('result.x = '+result.x.toString()+'',+'result.y = '+result.y.toString());

    //列印結果
    result.x = 40,result.y = 60
}

首先創建了一個Vector類,宣告兩個成員變數x和y還有一個構造方法,在Vector類里面多載一個加法運算子,多載操作回傳Vector物件,接下來在main函式里面,實體化了兩個Vector變數,兩次操作分別給

x和y進行了賦值,x = 10;y = 20;x = 30;y = 40,然后讓result1和result2這兩個變數相加,看到這里大家可能會有疑問,兩個物件變數怎么相加呢?這里我們的運算子多載就發揮出作用了,實際上,在執行final result = result1 + result2;這行代碼的時候,其實是物件result1呼叫了"operator +"這個函式,并將result2這個物件當作一個引數傳遞給了這個函式,從而實作了物件result1中的x和物件result2中的x相加,物件result1中的y和物件result2中的y相加的操作,所以最終列印的結果result.x = 40,result.y = 60,

注:對于 Dart 提供的所有運算子,通常只支持對于基本資料型別和標準庫中提供的類的操作,而對于用戶自己定義的類,如果想要通過該運算子實作一些基本操作(比如比較大小,判斷是否相等),就需要用戶自己來定義關于這個運算子的具體實作了,

  •  繼承類

繼承是面向物件編程技術的一塊基石,因為它允許創建分等級層次的類,繼承就是子類繼承父類的特征和行為,使得子類物件具有父類的實體域和方法;或子類從父類繼承方法,使得子類具有父類相同的行為,Dart里面使用extends關鍵字來實作繼承,super關鍵字來指定父類,

Class Animal {
    void eat(){
        print('動物會吃');
    }

    void run(){
        print('動物會跑');
    }
}

Class Human extends Animal {
    void say(){
        print('人會說');
    }

    void study(){
        print('人會學習');
    }
}

void main(){
    var animal = new Animal();
    animal.eat();
    animal.run();

    value human = new Human();
    human.eat();
    human.run();
    human.say();
    human.study();

    //列印結果
    動物會吃
    動物會跑

    動物會吃
    動物會跑
    人會說
    人會學習
}

 

  • 抽象類

抽象類類似于Java語言中的介面,抽象類里不具體實作方法,只是寫好定義介面,具體實作留著呼叫的人去實作,抽象類可以使用abstract關鍵字定義類,

  1. 抽象類通過abstract關鍵字來定義,
  2. Dart中的抽象方法不能用abstract宣告,Dart中沒有方法體的方法我們成為抽象方法,
  3. 如果子類繼承了抽象類,就必須實作里面的抽象方法,
  4. 如果把抽象類當作介面實作的話,就必須得實作抽象類里面的所有屬性和方法,
  5. 抽象類不能實體化,只有繼承它的子類可以實體化,
abstract class Animal{
    eat();   //抽象方法
    run();  //抽象方法  
    printInfo(){
    print('我是一個抽象類里面的普通方法');
  }
}

class Dog extends Animal{
    @override
    eat() {
        print('小狗在吃骨頭');
    }

    @override
    run() {
        // TODO: implement run
        print('小狗在跑');
    }  
}
class Cat extends Animal{
    @override
    eat() {
        // TODO: implement eat
        print('小貓在吃老鼠');
    }

    @override
    run() {
        // TODO: implement run
        print('小貓在跑');
    }

}

void main(){
    Dog d=new Dog();
    d.eat();
    d.printInfo();

    Cat c=new Cat();
    c.eat();
    c.printInfo();

    // Animal a=new Animal();   //抽象類沒法直接被實體化
}

 

Dart學習系列文章:https://www.cnblogs.com/jukaiit/category/1636484.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/165587.html

標籤:Dart

上一篇:谷歌瀏覽器之安裝插件(SwitchyOmega_Chromium)提示程式包無效:“CRX_HEADER_INVALID“

下一篇:jdk各個版本下載

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more