帶你快速掌握Scala操作———(4)

1、iterator迭代器

scala針對每一類集合都提供了一個迭代器(iterator)用來迭代訪問集合
使用迭代器遍歷集合
	使用iterator方法可以從集合獲取一個迭代器
	迭代器的兩個基本操作
	hasNext——查詢容器中是否有下一個元素
	next——返回迭代器的下一個元素,如果沒有,拋出NoSuchElementException
	每一個迭代器都是有狀態的
	迭代完後保留在最後一個元素的位置
	再次使用則拋出NoSuchElementException
	可以使用while或者for來逐個返回元素

示例

1.	定義一個列表,包含以下元素:1,2,3,4,5
2.	使用while循環和迭代器,遍歷打印該列表

參考代碼

scala> val ite = a.iterator
ite: Iterator[Int] = non-empty iterator

scala> while(ite.hasNext) {
    | println(ite.next)
    | }

示例

1.	定義一個列表,包含以下元素:1,2,3,4,5
2.	使用for 表達式和迭代器,遍歷打印該列表

參考代碼

scala> val a = List(1,2,3,4,5)
a: List[Int] = List(1, 2, 3, 4, 5)

scala> for(i <- a) println(i)

2、類和對象

scala是支持面向對象的,也有類和對象的概念。我們依然可以基於scala語言來開發面向對象的應用程序。
創建類和對象

用法

使用class來定義一個類 new來創建對象

參考代碼

object _01ClassDemo {
 // 創建類
 class Person{}

 def main(args: Array[String]): Unit = {
   // 創建對象
   val p = new Person()
   println(p)
}
}

參考代碼

object _02ClassDemo {

 // 創建類,省略花括號
 class Person

 def main(args: Array[String]): Unit = {
   // 創建對象,省略括號
   val person = new Person
}
}
定義和訪問成員變量
一個類會有自己的屬性,例如:人這樣一個類,有自己的姓名和年齡。在類中定義、和訪問成員變量

參考代碼

object _03ClassDemo {
 class Person {
   // 定義成員變量
   var name = ""
   var age = 0
}

 def main(args: Array[String]): Unit = {
   // 創建Person對象
   val person = new Person
   person.name = "zhangsan"
   person.age = 20

   // 獲取變量值
   println(person.name)
   println(person.age)
}
}

3、使用下劃線初始化成員變量

scala中有一個更簡潔的初始化成員變量的方式,可以讓代碼看起來更加簡潔。

用法

在定義var類型的成員變量時,可以使用_來初始化成員變量
	String => null
	Int => 0
	Boolean => false
	Double => 0.0...
val類型的成員變量,必須要自己手動初始化

參考代碼

object _04ClassDemo {

 class Person{
   // 使用下劃線進行初始化
   var name:String = _
   var age:Int = _
}

 def main(args: Array[String]): Unit = {
   val person = new Person
   
   println(person.name)
   println(person.age)
}
}

4、定義成員方法

類可以有自己的行爲,scala中也可以通過定義成員方法來定義類的行爲。
使用def來定義成員方法

示例

  1. 創建一個Customer類
    在這裏插入圖片描述

  2. 創建一個該類的對象,並調用printHello方法

步驟

1、創建一個Object,添加main方法
2、創建Customer類,添加成員變量、成員方法
3、在main方法中創建Customer類對象,設置成員變量值(張三、男)
4、調用成員方法

參考代碼

object _05ClassDemo {

 class Customer {
   var name:String = _
   var sex:String = _

   // 定義成員方法
   def sayHi(msg:String) = {
     println(msg)
  }
}

 def main(args: Array[String]): Unit = {
   val customer = new Customer
   customer.name = "張三"
   customer.sex = "男"
   customer.sayHi("你好")
}
}

5、訪問修飾符

和Java一樣,scala也可以通過訪問修飾符,來控制成員變量和成員方法是否可以被訪問。

定義

可以在成員前面添加private/protected關鍵字來控制成員的可見性。 
scala中,沒有public關鍵字,任何沒有被標爲privateprotected的成員都是公共的

案例

定義一個Person類

在這裏插入圖片描述

在main方法中創建該類的對象,測試是否能夠訪問到私有成員

參考代碼

object _02AccessDemo {

 class Person {
   // 定義私有成員變量
   private var name:String = _
   private var age:Int = _

   def getName() = name
   def setName(name:String) = this.name = name
   def getAge() = age
   def setAge(age:Int) = this.age = age

   // 定義私有成員方法
   private def getNameAndAge = {
     name -> age
  }
}

 def main(args: Array[String]): Unit = {
   val person = new Person
   person.setName("張三")
   person.setAge(10)

   println(person.getName())
   println(person.getAge())
}
}

6、類的構造器

當創建類對象的時候,會自動調用類的構造器。之前使用的都是默認構造器, 
主構造器
Java的構造器,有構造列表和構造代碼塊

class Person {
   // 成員變量
   private String name;
   private Integer age;

   // Java構造器
   public Person(String name, Integer age) {
       // 初始化成員變量
       this.name = name;
       this.age = age;
  }
}
在scala中, 可以使用更簡潔的語法來實現。

語法

class 類名(var/val 參數名:類型 = 默認值, var/val 參數名:類型 = 默認值){
   // 構造代碼塊
}
	主構造器的參數列表是直接定義在類名後面,添加了val/var表示直接通過主構造器定義成員變量
	構造器參數列表可以指定默認值
	創建實例,調用構造器可以指定字段進行初始化
	整個class中除了字段定義和方法定義的代碼都是構造代碼

示例

1.	定義一個Person類,通過主構造器參數列表定義姓名和年齡字段,並且設置它們的默認值
2.	在主構造器中輸出"調用主構造器"
3.	創建"張三"對象(姓名爲張三,年齡爲20),打印對象的姓名和年齡
4.	創建"空"對象,不給構造器傳入任何的參數,打印對象的姓名和年齡
5.	創建"man40"對象,不傳入姓名參數,指定年齡爲40,打印對象的姓名和年齡

參考代碼

object _06ConstructorDemo {

  // 定義類的主構造器
  // 指定默認值
  class Person(var name:String = "", var age:Int = 0) {
    println("調用主構造器")
  }

  def main(args: Array[String]): Unit = {
    // 給構造器傳入參數
    val zhangsan = new Person("張三", 20)
    println(zhangsan.name)
    println(zhangsan.age)

    println("---")

    // 不傳入任何參數
    val empty = new Person
    println(empty.name)
    println(empty.age)

    println("---")

    // 指定字段進行初始化
    val man40 = new Person(age = 40)
    println(man40.name)
    println(man40.age)
  }
} 
輔助構造器
除了主構造器之外的構造器稱爲輔助構造器。
例如:允許通過多種方式,來創建對象,這時候就可以定義其他更多的構造器。 

語法

	定義輔助構造器與定義方法一樣,也使用def關鍵字來定義
	這個方法的名字爲this
def this(參數名:類型, 參數名:類型) {
    // 第一行需要調用主構造器或者其他構造器
    // 構造器代碼
}
輔助構造器的第一行代碼,必須要調用主構造器或者其他輔助構造器

示例

示例說明
	定義一個Customer類,包含一個姓名和地址字段
	定義Customer類的主構造器(初始化姓名和地址)
	定義Customer類的輔助構造器,該輔助構造器接收一個數組參數,使用數組參數來初始化成員變量
	使用Person類的輔助構造器來創建一個"zhangsan"對象
	姓名爲張三
	地址爲北京
	打印對象的姓名、地址

參考代碼

object _07ConstructorDemo {
  class Customer(var name:String = "", var address:String = "") {
    // 定義輔助構造器
    def this(arr:Array[String]) = {
      // 輔助構造器必須要調用主構造器或者其他輔助構造器
      this(arr(0), arr(1))
    }
  }

  def main(args: Array[String]): Unit = {
    val zhangsan = new Customer(Array("張三", "北京"))

    println(zhangsan.name)
    println(zhangsan.address)
  }
}

7、單例對象

scala中沒有Java中的靜態成員,若想要定義類似於Java的static變量、static方法,就要使用到scala中的單例對象——object.
定義單例對象
單例對象表示全局僅有一個對象(類似於Java static概念)
	定義單例對象和定義類很像,就是把class換成object
	在object中定義的成員變量類似於Java的靜態變量
	可以使用object直接引用成員變量

示例

示例說明
	定義一個Dog單例對象,保存狗有幾條腿
	在main方法中打印狗腿的數量

參考代碼

	object _08ObjectDemo {
	
	  // 定義一個單例對象
	  object Dog {
	    // 定義腿的數量
	    val LEG_NUM = 4
	  }
	
	  def main(args: Array[String]): Unit = {
	    println(Dog.LEG_NUM)
	  }
	}
在單例對象中定義成員方法
	在object中定義的成員方法類似於Java的靜態方法

示例

示例說明
	設計一個單例對象,定義一個能夠打印分割線(15個減號)的方法
	在main方法調用該方法,打印分割線

參考代碼

object _09ObjectDemo {

  object PrintUtil {

    // 打印分割線
    def printSpliter() = {
      // 字符串乘法,表示返回多少個字符串
      println("-" * 10)
    }
  }

  def main(args: Array[String]): Unit = {
    PrintUtil.printSpliter()
  }
}

8、工具類案例

需求

	編寫一個DateUtil工具類專門用來格式化日期時間
	定義一個方法,用於將日期(Date)轉換爲年月日字符串,例如:2030-10-05

步驟

	定義一個DateUtil單例對象,定義日期格式化方法(format)
	使用SimpleDateFormat將日期轉換爲字符串

參考代碼

object _10ObjectDemo {

  object DateUtils {
    // 在object中定義的成員變量,相當於Java中定義一個靜態變量
    // 定義一個SimpleDateFormat日期時間格式化對象
    val simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm")

    // 相當於Java中定義一個靜態方法
    def format(date: Date) = simpleDateFormat.format(date)
  }

  // main是一個靜態方法,所以必須要寫在object中
  def main(args: Array[String]): Unit = {
    println(DateUtils.format(new Date()))
  }
}

9、main方法

scala和Java一樣,如果要運行一個程序,必須有一個main方法。在Java中main方法是靜態的,而在scala中沒有靜態方法。在scala中,這個main方法必須放在一個單例對象中。

定義main方法

main方法
def main(args:Array[String]):Unit = {
    // 方法體
}

示例

示例說明
	創建一個單例對象,在該單例對象中打印"hello, scala"

參考代碼

object Main5 {
  def main(args:Array[String]) = {
    println("hello, scala")
  }
}
實現App Trait來定義入口
創建一個object,繼承自App Trait(特質),然後將需要編寫在main方法中的代碼,寫在object的構造方法體內。
object 單例對象名 extends App {
    // 方法體
}

示例

示例說明
	繼承App特質,來實現一個入口。同樣輸出"hello, scala"

參考代碼

object Main5 extends App {
  println("hello, scala")
}

10、伴生對象

在Java中,經常會有一些類,同時有實例成員又有靜態成員。例如:

public class CustomerService {

private static String SERVICE_NAME = "CustomerService";

public void save() {
    // 保存客戶
    System.out.println(SERVICE_NAME + ":保存客戶");
}

public static void main(String[] args) {
    new CustomerService().save();
}
}
在scala中,要實現類似的效果,可以使用伴生對象來實現。

定義伴生對象

一個class和object具有同樣的名字。這個object稱爲伴生對象,這個class稱爲伴生類
	伴生對象必須要和伴生類一樣的名字
	伴生對象和伴生類在同一個scala源文件中
	伴生對象和伴生類可以互相訪問private屬性

示例

示例說明
	編寫一個CustomerService類,有一個save方法,打印
	服務類名稱:保存客戶
	編寫一個CustomerService伴生對象,定義一個私有變量,用於保存服務類名稱
	創建CustomerService對象,調用save方法

參考代碼

object _11ObjectDemo {

  class CustomerService {
    def save() = {
      println(s"${CustomerService.SERVICE_NAME}:保存客戶")
    }
  }

  // CustomerService的伴生對象
  object CustomerService {
    private val SERVICE_NAME = "CustomerService"
  }

  def main(args: Array[String]): Unit = {
    val customerService = new CustomerService()
    customerService.save()
  }
}
private[this]訪問權限
如果某個成員的權限設置爲private[this],表示只能在當前類中訪問。伴生對象也不可以訪問

示例

示例說明
	定義一個Person類,包含一個name字段
	定義Person類的伴生對象,定義printPerson方法
	測試伴生對象是否能訪問private[this]權限的成員

示例代碼

  class Person(private[this] var name:String)
  
  object Person {
    def printPerson(person:Person): Unit = {
      println(person.name)
    }
  }
  
  def main(args: Array[String]): Unit = {
    val person = new Person("張三")
    Person.printPerson(person)
  }

上述代碼,會編譯報錯。但移除掉[this]就可以訪問了

11、繼承

scala語言是支持面向對象編程的, 可以使用scala來實現繼承,通過繼承來減少重複代碼。

定義語法

	使用extends關鍵字來實現繼承
	可以在子類中定義父類中沒有的字段和方法,或者重寫父類的方法
	類和單例對象都可以從某個父類繼承

語法

class/object 子類 extends 父類 {
    ..
}
示例 | 類繼承
	定義一個Person類,再定義一個Student類,繼承自Person類

在這裏插入圖片描述

	創建一個Student類對象實例,並設置name爲“張三”
	打印姓名

參考代碼

class Person {
  var name = "super"

  def getName = this.name
}
class Student extends Person

object Main13 {
  def main(args: Array[String]): Unit = {
val p1 = new Person()
val p2 = new Student()

p2.name = "張三"

println(p2.getName)

}
}

示例 | 單例對象繼承

示例說明

	創建一個Student單例對象,讓單例對象繼承示例1中的Person類
	設置單例對象的名字爲"張三",調用Student單例對象的getName方法
class Person {
  var name = "super"

  def getName = this.name
}

object Student extends Person

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

    println(Student.getName)
  }
}

12、override和super

類似於Java語言, 在子類中使用override需要來重寫父類的成員,可以使用super來引用父類

用法

	子類要覆蓋父類中的一個方法,必須要使用override關鍵字
	使用override來重寫一個val字段
	使用super關鍵字來訪問父類的成員方法

示例

示例說明
	定義一個Person類,包含
	姓名字段(不可重新賦值)
	獲取姓名方法
	定義一個Student類
	重寫姓名字段
	重寫獲取姓名方法,返回"hello, " + 姓名
	創建Student對象示例,調用它的getName方法

參考代碼

class Person {
  val name = "super"

  def getName = name
}

class Student extends Person {
  // 重寫val字段
  override val name: String = "child"

  // 重寫getName方法
  override def getName: String = "hello, " + super.getName
}

object Main13 {
  def main(args: Array[String]): Unit = {
    println(new Student().getName)
  }
}

這篇就分享到這還有一部分下一篇給大家一起分享完!!!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章