Scala學習筆記(二)

Scala面向對象:

類:

聲明類(一個源文件中能夠包含不少public的類)
getter和setter
構造函數(主構造器和附屬構造器)
繼承(extends)
重寫父類方法(override def)
重寫字段(override val,override var)php

1.聲明類java

/** * * 在scala 中,類默認是public,並且一個源文件能夠包含多個public,源文件名能夠和文件中定義的類名不一致 */
class Person {
val name:String = "jack"
//普通類不容許聲明一個變量不給任何值的指定
var age:Int = _ //var 能夠不指定值,給個佔位符
//定義一個私有成員
// private[this] val gender:String = "male" //private 在哪一個包能訪問,其餘的包不能訪問
private[this] var gender:String = "male"
//能夠經過暴露一個getter來訪問類中的私有成員
def getGender:String = {
this.gender
}
def setGender(gender:String){
this.gender = gender
}
//定義成員方法
def sayHello(msg:String){
println(msg)
}
}
object Person{
def main(args: Array[String]): Unit = {
//默認無參構造函數,能夠不用帶括號
val p = new Person
println(p.name)
p.age = 18
println(p.age)
//跟java中同樣,不能對私有成員進行訪問 p.gender
println(p.getGender)
p.setGender("nonFemale")
println("new Gender: "+p.getGender)
p.sayHello("today is very fine,i like it")
}
}

2.構造函數:web

//class 有一個默認的無參構造器
//帶參的主構造器,就是在類名後指定參數,主構造器的參數會被編譯成類的成員變量(前提:參數必須有val或者var)
class Book(val name :String ,var price:Float) {
    //類定義中的語句其實就是在主構造器方法體中
    println("這是在Book類的主構造器")
    private[this] var author :String = _
  //附屬構造器,名稱必定是this,參數不能帶var或者val
   def this (name:String,price:Float,author:String){
       //必定要在第一行調用主構造器
     this(name,price);
     this.author = author
     println("這是在Book類附屬構造器中")
  }
    def  sayHello{
        println("hello world")
    }
   sayHello
}
object Book{
    def  main(args:Array[String]):Unit = {
     val b  = new Book("hadoop權威",100,"張三")
      println(b.name)
      println(b.price)
      b.price=80F;
      println("new price " + b.price);
    }
}

3.繼承:markdown

class TestExtends {
}
//先執行父類的構造函數,在執行子類的構造函數
//子類繼承父類的成員變量,因此在主類構造器中的相應參數能夠不帶val或者var,子類特有的成會員變量應該帶val或者var
class Teacher(val name:String,val age :Int ){
    val major :String = "math";
    println("在Teacher的主構造器中......")
}
class CollegeTeacher(name:String,age:Int,school:String) extends Teacher(name,age){
//重寫父類中的成員變量, 必須加override修飾符
    override  val major:String = "HighLevelMath"
    println("在CollegeTeacher的主構造器中......")
//在父類中已經實現的方法,子類重寫時必定要加override
  override def toString: String="override toString......"
}
object Runner{
  def main(args: Array[String]): Unit = {
    val ct = new CollegeTeacher("tom",33,"TsingHua")
    println(ct.toString)
    println(ct.major)
  }
}

抽象類(abstract class):網絡

類的一個或者多個方法沒有完整的定義
聲明抽象方法不須要加abstract關鍵字,只須要不寫方法體
子類重寫父類的抽象方法時不須要加override
父類能夠聲明抽象字段(沒有初始值的字段)
子類重寫父類的抽象字段時不須要加override,不然須要overrideapp

class TestAbstractClass {
}
//定義抽象類,要加abstract關鍵字
abstract class AbstractParent {
  //能夠定義有初始化的成員
  val name: String = "jack"
  //也能夠定義沒有初始化的成員,即抽象成員
  val age: Int
  //能夠定義有具體是實現的方法
  def add(x: Int, y: Int) = x + y
  //也能夠定義抽象方法
  def concat(a: String, b: String): String
  println("in the abstract parent......")
}
class son extends AbstractParent {
  //抽象的成員或者方法 在子類中實現時,不須要加override
  //抽象父類中的抽象成員在子類中必須實現
  //給個佔位符或者具體值
  val age:Int = 18
  //抽象父類中的抽象方法必須在子類中實現
  def concat(a:String,b:String):String = a+b
  //重寫抽象父類中的成員或者方法 ,必須加override
  override  val name :String = "tom"
  override  def add(x:Int,y:Int)= x+ y + 10
  println("in the son")
}
object son{
  def main(args: Array[String]): Unit = {
    val s = new son
    println("add function " + s.add(4,5))
  }
}

特質(trait)—-對比java8中的接口ide

字段和方法的集合
混入類中
經過with關鍵字,一個類能夠擴展多個特質函數

class TestTrait {
}
class AbstractParent01 {}
//定義一個trait特質
trait Logger {
//trait 中也能夠定義抽象方法
  def append(msg: String): Unit
//trait 中能夠定義具體實現的方法
  def log(info: String) {
    println("INFO: logging in traint Logger......" + info)
  }
}
trait ConsoleLogger extends Logger {
//子trait中能夠實現父trait中的抽象方法,也能夠不去實現,保持抽象
  def append(msg: String): Unit = {
    println("append in the ConsoleLogger......")
  }
//子trait能夠重寫父trait中有具體實現的方法,必定要加override關鍵字
  override def log(info: String) {
    println("INFO: logging in traint Logger......" + info)
  }
}
//一般用with來「繼承」trait, 可是若是子類沒有其餘的父類,則用extends 關鍵字來「繼承」trait
class ClassA extends AbstractParent01 with Logger {
//必須實現trait中的抽象方法
  def append(msg: String) {}
  val name: String = "jack"
}
class ClassB extends ConsoleLogger {
}
//定義一個普通類,在定義時沒有指定繼承任何trait,可是在建立時,能夠臨時混入trait
class ClassC{
}
object Runner01 {
  def main(args: Array[String]): Unit = {
    val ca = new ClassA
    println(ca.name)
    ca.log("Successfully with a trait")
    println("-------------------")
    val b = new ClassB
    b.log("User zhangsan loged in")
    println("------------------")
//能夠在建立對象時混入trait,擴展類的功能
    val c = new ClassC with ConsoleLogger
    c.log("Successful with a trait when instaniating a class")
  }

apply方法oop

單例對象this

class TestApply {
}
class AAA{
  def test(): Unit ={
    println("worked in class AAA")
  }
  def apply(): Unit ={
    println("apply in class AAA")
  }
}
object AAA{
//注意:此處的new AAA()是調用class AAA的構造器,返回的是AAA的是實例對象
//至關於一個建立類實例的普通工廠方法
//def apply()= new AAA()
//改造一下,就成了一個建立單例對象的工廠方法
  var aaa:AAA = _
  def apply() =  if(aaa == null ){aaa= new AAA();aaa}else aaa
}
object AAA0{
  def apply(): Unit ={
    println("apply in object AAAo")
  }
}
object Runner{
  def main(args: Array[String]): Unit = {
//apply方法能夠被顯示調用
      AAA0.apply()
//更多地是經過對象名加圓括號來調用
      AAA0()
//對象是同樣的道理
      val a  = new AAA
      a.apply()
      a()
//經過調用類AAA的伴隨object AAA的apply方法來初始化一個AAA類的實例對象
//apply方法一般就是經過這樣一種模式來爲一些類進行實例對象的建立
      val aaa = AAA()
      aaa.test
      val aaa1 = AAA()
      println(aaa.toString)
      println(aaa1.toString)
  }
}

模式匹配
標準用法(match)
使用守衛
匹配類型

object TestMatchCaseDemo {
  def main(args: Array[String]): Unit = {
    val a = 1
    a  match {
      case 1 => println("it is 1")
      case 2 => println("it is 2")
      case _ => println("other thing ")
    }
    a match{
      case x if x==1 => println("it is 1 again")
      case x if x==2 => println("it is 2 again")
      case _  => println("other thing again ")
    }
    def test(a:Int) =a match{
      case 1 => println("it is 1 in function ")
      case 2 => println("it is 2 in function")
      case _ => println("other thing in function")
    }
    test(3)
    def t(obj:Any) = obj match{
      case x:String => {println("it is a String ");x}
      case x:Int => println("it is a Int")
      case _ => println("it is some other ")
    }
    t(Array("tom"))
    println(t("jack"))
    }
}

case class(多用在模式匹配中)
構造器中的每個類型默認都爲val
不用new就能夠直接產生對象(爲何?apply方法)

class TestCaseClass {
}
//case class 用關鍵字 case 來定義
//主構造器中的參數不該加val或者var,也會被自動地編輯成成員變量
//在case class中,主構造器中的參數默認是val ,且不建議用var
case class User(name:String,psw:String){
}
object TestCaseClass {
  def main(args: Array[String]): Unit = {
    //得到一個case class 的實例對象,不用顯示new,而是直接"類名(參數)"就能夠(爲何?apply()方法)
       val u = User("tom","a good boy")
        u  match {
          //匹配類型的標準寫法
          //case i:User => println("it is a User......")
          //匹配類型的另外一種寫法,能夠根據傳入構造函數的具體字段進行精確匹配
          case User("tom","a good boy") => println("it is a User of tom and 123")
          case User("jack","a good boy") => println("it is a User of jack and 123")
          case  x:TestCaseClass => println("it is a TestCaseClass......")
          case _ => println("it is some other thing......")
        }
       //在scala中不少場景下可能會看到兩個case class:Some(表明有值) 和 None(表明無值),它們都是option的子類
       val m = Map(1->2,3->4);
       var x :Int = 0
       m.get(x) match {
         case Some(_) => println("key exists......")
         case None =>println("key not exists.....")
         case _  => println("other......")
       }
  }
}

文件訪問
按行讀取
按字符讀取
從網絡讀取

import scala.io.{Codec, Source}
class TestFileRead {
}
object TestFileRead{
  def main(args: Array[String]): Unit = {
    //讀取本地文件
    val file = Source.fromFile("F:\\上網帳號.txt")(Codec("GBK"))
    //按字符訪問
// for(c <- file){
// println(c)
// }
    //按行訪問
// for( file <- file.getLines()){
// println(file)
// }
    //讀取網頁
    val   webHtml = Source.fromURL("http://www.www.163.com/","GBK");
    for (line <- webHtml.getLines()){
        println(line)
    }
  }
}
相關文章
相關標籤/搜索