6. Scala面向對象編程(基礎部分)

来源:https://www.cnblogs.com/zhanghuicheng/archive/2019/04/29/10772142.html
-Advertisement-
Play Games

6.1 基本介紹 6.1.1 Scala語言是面向對象的 1) Java時面向對象的編程語言,由於歷史原因,Java中海存在著非面向對象的內容:基本類型,null,靜態方法等 2) Scala語言來自於Java,所以天生就是面向對象的語言,而且Scala時純粹的面相對象的語言,即在Scala中,一切 ...


6.1 基本介紹 

  6.1.1 Scala語言是面向對象的

      1) Java時面向對象的編程語言,由於歷史原因,Java中海存在著非面向對象的內容:基本類型,null,靜態方法等

      2) Scala語言來自於Java,所以天生就是面向對象的語言,而且Scala時純粹的面相對象的語言,即在Scala中,一切皆為對象

      3) 在面向對象的學習過程中可以對比著Java語言學習

  6.1.2 類和對象的區別和聯繫 

      1) 類是抽象的,概念的代表一類事物,比如人類,貓類...

      2) 對象是具體的,實際的,代表一個具體事物

      3) 類是對象的模版,對象是類的一個個體,對應一個實例

      4) Scala中類和對象的區別和聯繫和Java是一樣的

  6.1.3 如何定義類 

      -基本語法

        [修飾符] class 類名 {

          類體

        }

      -定義類的註意事項

        1) Scala語法中,類並不聲明為public,所有這些類都具有公有可見性(預設就是public)

        2) 一個Scala源文件可以包含多個類,而且預設都是public

  6.1.4 屬性 

      -基本介紹

        屬性是類的一個組成部分,一般是值數據類型,也可是引用類型

      -案例演示

class Dog {
  var name = "Tom"
  var lover = new Fish

}

class Fish {
  
}

  6.1.5 屬性/成員變數 

      -註意事項和細節說明

       1) 屬性的定義語法同變數,示例:[訪問修飾符] var 屬性名稱 [: 類型] = 屬性值

       2) 屬性的定義類型可以為任意類型,包含值類型或引用類型

       3) Scala中聲明一個屬性,必須顯示的初始化,然後根據初始化數據的類型自動推斷,屬性類型可以省略(這點和Java不同)

       4) 如果賦值為null,則一定要加類型,因為不加類型,那麼該屬性的類型就是Null類型

       5) 如果在定義屬性時,暫時不賦值,也可以使用符號_(下劃線),讓系統分配預設值

       

class A {
  var a1: String = _ //null
  var a2: Byte = _ // 0
  var a3: Double = _ // 0.0
  var a4: Boolean = _ // false
}

  6.1.6 屬性的高級部分 

      說明:屬性的高級部分和構造器(構造方法/函數)相關,具體介紹將在構造器部分詳解

  6.1.7 如何創建對象 

      -基本語法

      val | var 對象名 [: 類型] = new 類型()

      -說明

      1) 如果我們不希望改變對象的引用(即:記憶體地址),應該聲明為val性質的,否則聲明為var,Scala設計者推薦使用val,因為一般來說,在程式中,我們只是改變對象屬性的值,而不是改變對象的引用

      2) Scala在聲明對象變數時,可以根據創建對象的類型自動推斷,所以類型聲明可以省略,但當類型和後面new對象類型有繼承關係時即多態,就必須寫了

      3) 案例演示

object boke_demo01 {
  
  def main(args: Array[String]): Unit = {
    val emp = new Emp // emp 類型就是Emp
    //如果我們希望將子類對象,交給父類的引用,這時就需要寫上類型
    val emp2: Person = new Emp

  }
}

class Person {

}

class Emp extends Person {
  
}

  6.1.8 類和對象的記憶體分配機制 

      -案例演示

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    val p1 = new Person2
    p1.name = "jack"
    p1.age = 10

    val p2 = p1
    println(p1 == p2) // true
    p1.name = "tom"
    println("p2.name=" + p2.name) // p2.name=tom
  }

}

class Person2 {
  var name = ""
  var age: Int = _ //如果是用 _ 方式給預設值,則屬性必須指定類型
}

      -案例演示對應的記憶體佈局圖

6.2 方法 

  6.2.1 基本說明 

      Scala中的方法其實就是函數,聲明規則請參考函數式編程中的函數聲明

  6.2.2 基本語法 

      def 方法名[: 返回值類型] = {

        方法體

      }

  6.2.3 方法案例演示 

      給Cat類添加cal方法,可以計算兩個數的和

object MethodDemo01 {
  def main(args: Array[String]): Unit = {
    val cat = new Cat
    println(cat.cal(10, 20))
  }
}

class Cat {
  private var sal: Double = _
  var food: String = _

  //方法
  def cal(n1: Int, n2: Int): Int = {
    return n1 + n2
  }
}

6.3 構造器 

  6.3.1 看一個需求 

      我們來看一個需求:前面我們在創建Person的對象時,是先把一個對象創建好後,再給他的姓名和年齡屬性賦值,如果現在要求,在創建Person類對象時,就直接制定這個對象的姓名和年齡,該怎麼做?這時就可以使用構造方法/構造器

  6.3.2 回顧-Java構造器基本語法 

      [修飾符] 方法名 (參數列表) {

        構造方法體

      }

  6.3.3 回顧-Java構造器的特點 

      1) 在Java中一個類可以定義多個不同的構造方法,構造方法重載

      2) 如果程式員沒有定義構造方法,系統會自動給類生成一個無參構造方法(也叫預設構造器),比如:Person(){}

      3) 一旦定義了自己的構造方法(構造器),預設的構造方法就覆蓋了,就不能使用預設的無參構造方法,除非顯示的定義一下,即:Person(){}

  6.3.4 Java構造器案例 

      在前面定義的Person類中添加兩個構造器

      第一個無參構造器:利用構造器設置所有人的age屬性初始值都為18

      第二個帶name和age兩個參數的構造器:使得每次創建Person對象的同時初始化對象的name屬性值和age屬性值

public class Person {

    public String name;
    public int age;

    public String getInfo() {
        return name + "\t" + age;
    }

    public Person() {
        age = 18;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

}

  6.3.5 Scala構造器的介紹

      和Java一樣,Scala構造對象也需要調用構造方法,並且可以有任意多個構造方法(即Scala中構造器也支持重載),Scala類的構造器包括:主構造器和輔助構造器

  6.3.6 Scala構造器的基本語法 

      class 類名(形參列表) {  //主構造器

        def this(形參列表){  //輔助構造器

        }

        def this(形參列表){  //輔助構造器可以有多個...

        }

      }

      輔助構造器的函數名this,可以有多個,編譯器通過不同參數來區分

  6.3.7 Scala構造器的快速入門 

      創建Person對象的同時初始化對象的name屬性和age屬性,案例演示

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    //    val p1 = new Person("Jack", 20)
    //    println(p1)

    //下麵這句話就會調用def this(name:String)
    val p2 = new Person("Tom")
    println(p2)
  }
}

//構造器的快速入門
//創建Person對象的同時初始化對象的age屬性值和name屬性值
class Person(inName: String, inAge: Int) {
  var name: String = inName
  var age: Int = inAge
  age += 10
  println("~~~~~~~~~~")

  //重寫了toString,便於輸出對象的信息
  override def toString: String = {
    "name=" + this.name + "\t age" + this.age
  }

  println("ok~~~~~")
  println("age=" + age)

  def this(name: String) {
    //輔助構造器,必須在第一行顯式調用主構造器(可以是直接,也可以是間接)
    this("Jack", 10)
    //this
    this.name = name //重新賦值
  }
}

  6.3.8 Scala構造器註意事項和細節說明 

      1) Scala構造器的作用是完成對新對象的初始化,構造器沒有返回值

      2) 主構造器的聲明直接放置於類名之後

      3) 主構造器會執行類定義中的所有語句,這裡可以體會到Scala的函數式編程和麵向對象編程融合在一起,即:構造器也是方法(函數),傳遞參數和使用方法和前面的函數部分內容沒有區別

      4) 如果主構造器沒有參數,小括弧可以省略,構建對象時調用的構造方法的小括弧也可以省略

class AA {

}

val a = new AA
val b = new AA()

      5) 輔助構造器名稱為this(這個和Java是不一樣的),多個輔助構造器通過不同參數列表進行區分,在底層就是構造器重載

object boke_demo01 {

  def main(args: Array[String]): Unit = {

    val p1 = new Person2("jack")
    p1.showInfo()
  }
}

//定義了一個Person類
//Person 有幾個構造器 4
class Person2 private() {
  var name: String = _
  var age: Int = _

  def this(name: String) {
    //輔助構造器無論是直接或間接,最終都一定要調用主構造器,執行主構造器的邏輯
    //而且需要放在輔助構造器的第一行[這點和java一樣,java中一個構造器要調用同類的其它構造器,也需要放在第一行]
    this() //直接調用主構造器
    this.name = name
  }

  //輔助構造器
  def this(name: String, age: Int) {
    this() //直接調用主構造器
    this.name = name
    this.age = age
  }

  def this(age: Int) {
    this("匿名") //調用主構造器,因為 def this(name : String) 中調用了主構造器!
    this.age = age
  }

  def showInfo(): Unit = {
    println("person信息如下:")
    println("name=" + this.name)
    println("age=" + this.age)
  }
}

      6) 如果想要主構造器編程私有的,可以在()之前加上private,這樣用戶只能通過輔助構造器來構造對象了,比如: class Person2 private(){}

      7) 輔助構造器的聲明不能和主構造器的聲明一致,會發生錯誤(即構造器名重覆)

6.4 屬性高級

      對屬性的內容做一個加強

  6.4.1 構造器參數 

      1) Scala類的主構造器的形參未用任何修飾符修飾,那麼這個參數是局部變數

      2) 如果參數使用val關鍵字聲明,那麼Scala會將參數作為類的私有隻讀屬性使用

      3) 如果參數使用var關鍵字聲明,那麼Scala會將參數作為類的成員屬性使用,並會提供對應的xxx()[類似getter]/xxx_$eq()[類似setter]方法,即這時的成員屬性是私有的,但是可讀寫

      4) 案例演示 

object boke_demo01 {

  def main(args: Array[String]): Unit = {

    val worker = new Worker("smith")
    worker.name //不能訪問 inName

    val worker2 = new Worker2("smith2")
    worker2.inName  //可以訪問 inName
    println("hello!")

    val worker3 = new Worker3("jack")
    worker3.inName = "mary"
    println(worker3.inName)
  }
}

//如果 主構造器是Worker(inName: String) ,那麼 inName就是一個局部變數
class Worker(inName: String) {
  var name = inName
}
//如果 主構造器是Worker2(val inName: String) ,那麼 inName就是Worker2的一個private的只讀屬性
class Worker2(val inName: String) {
  var name = inName
}

// 如果 主構造器是Worker3(var inName: String) ,那麼 inName就是Worker3的一個
// 一個private 的可以讀寫屬性
class Worker3(var inName: String) {
  var name = inName
}

  6.4.2 Bean屬性 

      JavaBean規範定義了Java的屬性是像getXxx()和setXxx()方法。許多Java工具(框架)都依賴這個命名習慣。為了Java的互操作性。將Scala欄位加@BeanProperty時,這樣會自動生成規範的setXxx/getXxx方法。這時可以使用 對象.setXxx()和 對象.getXxx()來調用屬性

      註意:給某個屬性加入@BeanPropetry註解後,會生成getXxx和setXxx的方法,並且對原來底層自動生成類似xxx(),xxx_$eq()方法,沒有衝突,二者可以共存

import scala.beans.BeanProperty

object boke_demo01 {

  def main(args: Array[String]): Unit = {
    val car = new Car
    car.name = "寶馬"
    println(car.name)

    //使用 @BeanProperty 自動生成 getXxx 和 setXxx
    car.setName("賓士")
    println(car.getName())
  }
}

class Car {
  @BeanProperty var name: String = null
}

6.5 Scala對象創建的流程分析 

  6.5.1 看一個案例  

class Person {
  var age: Short = 90
  var name: String = _

  def this(n: String, a: Int) {
    this()
    this.name = n 
    this.age = a
  }

}

var p: Person = new Person ("小倩", 20)

  6.5.2 流程分析(面試題-寫出) 

      1) 載入類的信息(屬性信息,方法信息)

      2) 在記憶體中(堆)開闢空間

      3) 使用父類的構造器(主和輔助)進行初始化

      4) 使用主構造器對屬性進行初始化[age:90, name:null]

      5) 使用輔助構造器對屬性進行初始化[age:20, name:小倩]

      6) 將開闢的對象的地址賦給p這個引用

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 鑒於最近跟小伙伴聊了很多PHP架構發展方向的問題,相關技術整理了一下,也順便規划了一下自己的2019年。 一.常用的設計模式以及使用場景 以下是我用到過的 工廠,單例,策略,註冊,適配,觀察者,原型,裝飾器,facade,loc,pipeline 二.閱讀一個框架源碼 例如:laravel 三.常用 ...
  • 1.1 你是如何認識新事物的? 一般而言,從過往的見多的事物中,總結->推斷->所屬類別->認知行為。 1.2 類(Class)的概念 類是對一組具有共同特征和行為的對象的抽象描述。 理解 [1]類是專門用於描述現實生活中的事物的。 [2]類描述的事物都具有共同的特征和行為。 [3]類就是我們通常所 ...
  • 本人是做java web開發的,已經工作兩年了。一直都是自己學習學技術,昨天突然靈光一現,覺得自己應該有一個自己的博客。以後我會不定時的在博客上更新一些自己學習掌握的技術。以前都沒有過這樣書面性的給別人講解技術的經驗,可能有什麼寫的不到位的地方,請大家能夠給我指出來說明一下,我會加以改正。大家一起努 ...
  • 思路 首先以那個環為框架,把所有的邊連出來。如果有兩條邊相交,那麼就把其中一條放到環外面去。 ...
  • 一直以來Base64演算法的加密解密都是使用sun.misc包下的BASE64Encoder及BASE64Decoder來進行的。但是這個類是sun公司的內部方法,並沒有在Java API中公開過,不屬於JDK標準庫範疇,但在JDK中包含了該類,可以直接使用。但是在Eclipse和MyEclipse中 ...
  • 題意 給定一張圖,對於每條邊給出一個運算符$(\&,|,\otimes)$和一個值$c(0 \le c \le 1)$。問能否 ...
  • 今日目標 能夠計算二進位和十進位數之間的互轉 能夠使用常見的DOS命令 理解Java語言的跨平臺實現原理 jvm是運行java程式的假想電腦,所有的java程式都運行在它上面。java編寫的軟體可以運行在任何操作系統上,這被稱為java跨平臺特性,是由jvm實現的,java程式運行在jvm上,jv ...
  • 所屬網站分類: 面試經典 > python 作者:外星人入侵 鏈接:http://www.pythonheidong.com/blog/article/67/ 來源:python黑洞網,專註python資源,python教程,python技術 Python支持5種數據類型: 1. Numbers(數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...