1. 程式人生 > >[Scala]學習筆記三——面向物件

[Scala]學習筆記三——面向物件

一、面向物件的概 (Object Oriented——OO)

1.封裝: 將屬性、方法封裝到類中
2.繼承: 父類和子類之間的關係
3.多型: 父類引用指向子類物件
多型是面向物件程式設計的精髓所在,是開發框架的基礎

二、類的定義和使用

//main方法
 def main(args: Array[String]): Unit = {
    val person=new Person()
    person.name="Messi"
    println(person.eat)
    person.info
    person.watch("mexico")
}

//定義一個Person類
class Person{
  var name:String=_     				//_為萬用字元
  val age=10       						   //age定義為val型別了,則不可以改變了
  private [this] val gender="male"      //宣告為private[this],則只能在這個類中呼叫這個屬性,在main方法中調用不了

  def watch(team:String): Unit ={
    println(name+" watching race of "+team)
  }
  def eat: String ={
    name+" eat..."
  }
  def info: Unit ={
    println(name+"  "+age+" "+gender)
  }
}

結果:
Messi eat...
Messi  10 male
Messi watching race of mexico

三、主構造器和附屬構造器

附屬構造器的第一行必須要呼叫主構造器

//main方法
def main(args: Array[String]): Unit = {
    val person=new Person("Nina",23)
    println(person.age+"   "+person.name+"   "+person.school+"   "+person.gender)
    val person2=new Person("Nina",23,"female")
    println(person2.name+"  "+person2.age+"   "+person2.school+"   "+person2.gender)
}
//主構造器
class Person(val name:String,val age:Int){
    println("Person Constructor start…")
    val school="neu"
    var gender:String=_      		 //用佔位符的變數必須先宣告其型別
    println("Person Constructor stop…")

    //附屬構造器
    def this(name:String,age:Int,gender:String){
      this(name,age) 				     //附屬構造器第一行必須要呼叫主構造器
      this.gender=gender
    }
}

結果:
Person Constructor start…
Person Constructor stop…
23   Nina   neu   null
Person Constructor start…
Person Constructor stop…
Nina  23   neu   female

四、繼承extends和重寫override

//main方法
def main(args: Array[String]): Unit = {
    val student=new Student("Nina",23,"computor")
    //println(student.name+"  "+student.age+"   "+student.major)
    println(student)
}
//定義一個Student類,繼承Person類
//繼承父類的引數可以不用var/val定義,但該類新有的引數需要使用var/val來定義,如下面的major屬性
class Student(name:String,age:Int,var major:String) extends Person(name,age){
    println("Student constructor start…")

    override def toString: String ={			//子類繼承來的方法和屬性都可以重寫,需要使用override來宣告
      name+"  "+age+"  "+major
    }
    println("Student constructor stop…")
}

結果:
Person Constructor start…
Person Constructor stop…
Student constructor start…
Student constructor stop…
Nina  23  computor

五、抽象類abstract

抽象類是指:類中一個或多個方法沒有完整的實現(只有定義,沒有實現)

//main方法
def main(args: Array[String]): Unit = {
    val student=new Student()
    student.name="Nina"
    student.age=23
    println(student.name+"  "+student.age)
    student.speak
}

//定義一個抽象類
abstract class People{
  def speak
  var name:String
  var age:Int
}

//定義一個類,繼承該抽象類,並實現所有屬性和方法
class Student extends People{
  override def speak: Unit = {
    println("speak……")
}
override var name: String = _
override var age: Int = _
}

結果:
Nina  23
speak……

六、伴生類和伴生物件

如果有一個class,還有一個與class同名的object
那麼就成這個object是class的伴生物件,class是object的伴生類

七、Apply

1.直接類名. 便可以訪問object中的方法和屬性

object ApplyApp {
  def main(args: Array[String]): Unit = {
      for(i<-1 to 10)
      TestApply.incu              //直接類名. 便可以訪問object中的方法和屬性
      println(TestApply.count)
  }
}

//伴生類
class TestApply{
}

//伴生物件
object TestApply{
  println("object TestApply enter...")
  var count=0
  def incu: Unit ={
    count=count+1
  }
  println("object TestApply leave...")
}

結果:
object TestApply enter...
object TestApply leave...
10

2.類名() ==>呼叫object中的apply()方法

object ApplyApp {
  def main(args: Array[String]): Unit = {
    val a=TestApply()               //類名() ==>呼叫object中的apply()方法
  }
}

class TestApply{
  println("class TestApply enter...")
  def apply()={
    println("class apply enter...")
  }
  println("class TestApply leave...")
}

object TestApply{
  println("object TestApply enter...")
  def apply()={
    println("object apply enter...")
  }
  println("object TestApply leave...")
}

結果:
object TestApply enter...
object TestApply leave...
object apply enter..

3.物件()==>呼叫class中的apply()方法

object ApplyApp {
  def main(args: Array[String]): Unit = {
  	//val a=TestApply()               //類名() ==>呼叫object中的apply()方法
    val b=new TestApply()
    b()                             //物件()==>呼叫class中的apply()方法
  }
}

class TestApply{
  println("class TestApply enter...")
  def apply()={
    println("class apply enter...")
  }
  println("class TestApply leave...")
}

object TestApply{
  println("object TestApply enter...")
  def apply()={
    println("object apply enter...")
    //new TestApply()                 //最佳實踐:在object的apply()方法中new一個class的新物件
  }
  println("object TestApply leave...")
}

結果:
class TestApply enter...
class TestApply leave...
class apply enter...

八、case class

case class 不用new,直接可以使用,通常用在模式匹配中

object CaseClassApp {
  def main(args: Array[String]): Unit = {
    println(Dog("WangCai").name)			//沒有new一個Dog物件,而直接使用了
  }
}

case class Dog(name:String){

}

結果:
WangCai

九、trait

XXX extends … with … with… 實現的第一個介面用extends,之後的用with…