Scala之面向對象

1. Scala基礎練習

  1. 不使用str.toLong,str.toInt/Integer.valueOf()/Long.valueOf/Integer.parseInt()等,將字符串"123456789" 轉化成數字123456789java

    def method3(): Unit = {
       val str = "123456789"
       var sum = 0L
       for(ch <- str) {//字符串自己就是一個字符數組
           sum = sum * 10 + (ch - '0')
      }
       println(sum)

       str.toCharArray.map(ch => ch - '0').reduce((v1, v2) => v1 * 10 + v2)
    }
  2. 使用scala完成選擇排序web

       def main(args: Array[String]): Unit = {
          val array = Array(1, 5, 3, 5, 6, 7, 2, 9)
          println("排序前的數組:" + array.mkString("[", ", ", "]"))
          selectSort(array)
          println("排序後的數組:" + array.mkString("[", ", ", "]"))
      }
      /**選擇排序
        *
        */
      def selectSort(arr:Array[Int]): Unit = {
          for(i <- 0 until arr.length) {
              for (j <- i until arr.length) {
                  if(arr(i) > arr(j)) {
                      swap(arr, i, j)
                  }
              }
          }
      }
      /*
          位運算 ^ 相同爲0,反之爲1
          a=3 b=5
          a=0011
          b=0101
          a= a^b =0110
                  0101
          b= a^b =0011=3
                  0110
          a= a^b= 0101=5
          這裏沒有使用第三方變量完成兩個數字的交換,其中使用^與那孫效率最高
       */
      def swap(arr:Array[Int], i:Int, j:Int): Unit = {
          /*arr(i) = arr(i) ^ arr(j)
          arr(j) = arr(i) ^ arr(j)
          arr(i) = arr(i) ^ arr(j)*/
          arr(i) = arr(i) + arr(j)
          arr(j) = arr(i) - arr(j)
          arr(i) = arr(i) - arr(j)
      }
  3. 使用scala完成二分查找數組

    在一個有序數組中找到某一個值,若是存在,返回索引,沒有返回-1或者返回若是存在,應該在的位置
    def binarySearch(arr:Array[Int], key:Int):Int = {
          var start = 0
          var end = arr.length - 1
          while(start < end) {
              val mid = (start + end) / 2
              if (key < arr(mid)) {
                  //左邊
                  end = mid - 1
              } else if (key > arr(mid)) {
                  //又變
                  start = mid + 1
              } else {
                  return mid
              }
          }
          return -(start + 1)
      }

     

2. scala面向對象

2.1. 類的基本操做

2.1.1. 類的建立與對象的構造

* 定義scala中的類使用關鍵字class
*     1、定義scala中的任意一種結構,都不可使用public關鍵字修飾,由於scala中沒有public關鍵字
*         不加任何訪問權限修飾符就至關於java中的public
*     2、類中能夠定義成員信息
*         成員變量
*         成員方法
*     3、建立類的實例--對象
*         在scala中和java中是同樣,都使用關鍵字new來構建類的實例
object ClassOps {
   def main(args: Array[String]): Unit = {
       val p:Person = new Person()
       p.name = "劉夢男"
       p.age = 18
       p.show()
  }
}

class Person {
   var name:String = _
   var age:Int = _

   def show(): Unit = {
       println(s"name: ${name}\tage: ${age}")
  }
}

2.1.2. 成員變量的封裝getter和setter

*     4、scala無法直接爲成員變量提供getter和setter方法,只能本身編寫
*         scala作了一種嘗試,經過註解(@BeanProperty)的方式來給成員變量提供getter和setter,
*         前提是該getter或者setter不能被private修飾,此時數據的安全性沒法獲得保證
*
*     5、這個getter和setter的的使用其實javabean中的規範,javabean的主要做用是什麼?
*         封裝、傳遞數據
*         javaee
*             dao
*             service
*             web
*             domain
*                 Person
*                 Order
*                 Cat
*                 OrderItem
*                 Category
object ClassOps {
   def main(args: Array[String]): Unit = {
       val p:Person = new Person()
//       p.name = "liumengn"
//       p.age = 18

       p.setName("liwei")
       p.setAge(-2)
       p.setSalary(123.0f)
       p.show()
  }
}

class Person {
   private var name:String = _
   private var age:Int = _

   @BeanProperty var salary:Float = _
   def setName(n:String) = {
       name = n //單行函數
  }

   def getName = name

   def setAge(a:Int) = {
       if(a < 0) {
           throw new RuntimeException("what are you fucking 賦值!")
      }
       age = a
  }

   def getAge = age

   def show(): Unit = {
       println(s"name: ${name}\tage: ${age}")
  }
}

2.1.3. case class模擬javabean

/*
    在scala中通常不用這些普通的class類進行封裝數據、傳遞數據,那用什麼呢?
 *         case class樣例類
 *             做用就至關於java bean
 *   case class的定義很是簡單,在class關鍵字的前面加上另一個關鍵字case便可
 *  
 *   樣例類的定義必需要有一個參數列表---->構造器,
 *   case class的應用是很是普遍的,但凡數據的傳遞,通常都用case class
*/
object _02CaseClassOps {
   def main(args: Array[String]): Unit = {
val category = Category(1, "手機")
       println(category.id)
       println(category.name)
  }
}
//定義了一個case class Category
case class Category(id:Int, name:String)

2.1.4. scala類的構造器

*  2、構造器:
*     按照java中的知識,val stu = new Student是使用Student類的無參構造器建立對象
*     在一個類中,若是局部變量和成員變量名發生衝突,便經過給成員變量加this關鍵字進行區分
*  3、如何定義構造器:
*        嘗試使用def Student(name:String, age:Int)定義構造器,
*        調用的時候:
*         new Student("陳達", 20) too many arguments to constructor報錯
*         因此該方法就不是scala中的構造器
*  4、scala的構造,分爲主構造器和輔助構造器,
*     主構造器的定義和類的定義交織在一塊兒,如何去定義一個主構造器
*     class Xxx(參數列表) {
*     }
*     類名後面的內容就是主構造器,若是參數列表爲空的話,()能夠省略
*     主構造器的函數體,就是類體的內容,因此若是咱們使用主構造器建立對象
*  5、scala的類有且僅有一個主構造器,要想提供更加豐富的構造器,就須要使用輔助構造器
*     def this(參數列表)
*     scala中的輔助構造器,在函數體的第一行,必須以調用其它輔助構造器或者主構造器開始
*     也就是說要使用this(參數列表)去調用其它構造器
*     可是歸根到底,一個輔助構造器最終仍是要從主構造器的調用開始
*  6、scala和java的構造器的區別
*     java的構造器沒有主構造器和輔助構造器之分,可是有默認的無參構造器和有參構造器之分
*     scala中默認的構造器就是類名後面的構造器,被稱之爲主構造器,同時還擁有輔助構造器
*     java的構造器名稱和類名一直,而scala中的構造器名稱就是this,其他和java如出一轍
class Student(n:String, a:Int) {

   private var name:String = _
   private var age:Int = _

   def Student(name:String, age:Int): Unit = {
       this.name = name
       this.age = age
  }
   //輔助構造器
   def this() {
       this("張鍾方", 18)
       println("---輔助構造器def this()-----")
  }

   def this(age:Int) {
       this()
       this.age = age
       println("---輔助構造器def this(age:Int)-----")
  }

   def show(): Unit = {
       println(s"name: ${n}\tage: ${a}")
  }
   println("若是這是構造器的方法體的話,這句話應該會被調用!")
}

2.1.5. 嵌套類

scala中稱之爲嵌套類,在java中稱之爲內部類安全

java中的成員內部類實例app

public class InnerClassOps {
   public static void main(String[] args) {
       Outer.Inner oi = new Outer().new Inner();
       oi.show();
  }
}
class Outer {
   class Inner {
       public void show() {
           System.out.println("inner show");
      }
  }
}

爲啥要有內部類?dom

從業務邏輯上理解,定義複雜是否在外部類內部定義更加合理,這樣便有了內部類,好比,定義一個類Person,類有心臟,Heart優點一個複雜的抽象事物,顯然應該把Heart定義在Person內部更加的準確與合理。函數

scala的內部類如何定義this

object _03InnerOps {
   def main(args: Array[String]): Unit = {
       val outer = new Outer
       val inner = new outer.Inner()
       inner.show()
  }
}

class Outer { oo => //外部類的引用
   var x = 5
   class Inner {
       var x = 6
       def show(): Unit = {
           var x = 7
           println("Inner: x=" + x)//7
           println("Inner: x=" + this.x)//6
           println("Inner: x=" + Outer.this.x)//5
           println("Inner: x=" + oo.x)//5 簡寫方式
      }
  }
}

2.1.6. 對象object

scala並無像java中的靜態,因此按照java中的觀點的話,主函數是沒有辦法被執行public static void main(xxx)atom

scala爲了來模擬java中的static這個關鍵字,設計出了object這一結構,它是和class平級。spa

在object定義的方法咱們能夠理解爲函數,class中的行爲稱之爲方法,並且在object中定義的變量和函數都是能夠當作java中的靜態來進行調用。

object _04ObjectOps {
  def main(args: Array[String]): Unit = {
      val ret = Tool.add(13, 14)//至關於java的靜態方法
  }
}
object Tool {
  val x = 5
  def add(a:Int, b:Int) = a + b
}

如何在scala中去定義單例對象呢?

java中的單例(必須掌握)

/**
* 單例
*     惡漢式
*     懶漢式
* 一個類只能建立一個對象,
* 定義的步驟:
*   惡漢式:
*     一、私有構造器
*     二、提供一個public的static的返回值爲本類引用的方法
*     三、爲了給第2步中提供實例,建立一個private的static的成員變量
*   懶漢式:
*     一、私有構造器
*     二、建立一個private的static的成員變量,沒有初始化
*     三、提供一個public的static的返回值爲本類引用的方法
*/

惡漢式:

class Singleton {//惡漢式
   private Singleton(){}
   //成員位置
  {//構造代碼塊

  }
   private static Singleton instance = new Singleton();
//   static {
//       instance = new Singleton();
//   }

   public static Singleton getInstance() {
       return instance;
  }
}

懶漢式:

class Singleton {
   private Singleton(){}
   private static Singleton instance;

   public static Singleton getInstance() {
       if(instance == null) {
           synchronized (Singleton.class) {
               if(instance == null)
                   instance = new Singleton();
          }
      }
       return instance;
  }
}

scala中的單例

object _05SingletonOps {
   def main(args: Array[String]): Unit = {
       val s1 = Singleton
       val s2 = Singleton
       println("s2.x=" + s2.x)//1
       s1.x = 5
       println("s1 == s2? " + (s1 == s2))//true 單例
       println("s2.x=" + s2.x)//5
  }
}
object Singleton {
   var x = 1
}

2.1.7. 伴生對象和伴生類

爲何要有伴生對象?

咱們都知道,在scala中是沒有靜態這個概念,而在java中一個類是既能夠有非靜態的成員,也能夠有靜態成員,表達很是豐富。scala因爲沒有靜態的概念,類只能擁有非靜態成員。因此scala爲了彌補這個缺憾,定義這麼一個和該類同名的object結構,並且該object結構必需要和該類在同一個.scala源文件中被定義

這樣咱們就可讓該類擁有了靜態和非靜態的成員。

把這個和類同名的object稱之爲該類的伴生對象,反過來,該類稱之爲該object的伴生類。

object _06CompanionOps {
   def main(args: Array[String]): Unit = {
       val worker = new Worker("old李", 38)
       worker.show()
       println("-----------------------------")

       val w1 = Worker()
       w1.show()
       println("靜態屬性:" + Worker.x)
       val w2 = Worker("蔡金廷", 13)
       w2.show()

//       val arr = new Array[Int](5)
//       val arr1 = Array(1, 2, 3, 4)
  }
}

class Worker /*private ()*/ {
   private var name:String = _
   private var age:Int = _

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

   def show(): Unit = {
       println(s"name:${name}, age:${age}")
  }
}

object Worker {
   var x = 123
   //apply方法必需要重寫
   def apply(): Worker = new Worker()

   def apply(name: String, age: Int): Worker = new Worker(name, age)
}

2.1.8 沒有main函數如何執行scala程序

object _07AppOps extends App {
   /*def main(args: Array[String]): Unit = {
       println("xxxxxx")
   }*/
   println(args.mkString("[", ",", "]"))
   println("yyyyyyyyyyyy")
}
extends:擴展
trait:特質

 

相關文章
相關標籤/搜索