Scala - 抽象、繼承、多態

抽象

scala的抽象關鍵字和java同樣,都是abstract,並且抽象類都不能被實例化的。
除了類能夠定義爲抽象的,類的屬性和方法,也能夠是抽象的。
從下面的例子中,能夠看到其實和java的抽象類定義沒有什麼區別java

abstract class ScalaAbstract {
  // 抽象屬性,能夠沒有初始值,甚至不用_
  var str1: String
  var str2: String = "str2"
  val str3: String
  val str4: String = "str4"

  /**
   * 抽象方法
   */
  def printInfo1: Unit

  def printInfo2: Unit = {
    println(s"${str1},${str2},${str3},${str4}")
  }
}

繼承

和java同樣,繼承也是用extends關鍵字,概念也是同java的,包括先調用父類的構造器等。區別以下:ide

  1. 若是覆蓋父類的非抽象方法,非抽象變量,在scala中要寫override,在java中只是警告。
  2. 抽象方法,var定義的抽象變量,能夠不寫override,也能夠寫。
  3. val定義的抽象變量,要寫override。
class ScalaChild extends ScalaAbstract {
  /**
   * 能夠不寫override
   */
  var str1: String = "str1"
  /**
   * 直接修改
   */
  str2 = "str2"
  /**
   * 必須寫override
   */
  override val str3: String = "str3"
  /**
   * 必須寫override
   */
  override val str4: String = "str4"

  /**
   * 抽象方法,能夠不寫override
   */
  def printInfo1: Unit = {
    println(s"${str1},${str2},${str3},${str4}")
  }

  /**
   * 必須寫override
   */
  override def printInfo2: Unit = {
    println(s"ScalaChild:${str1},${str2},${str3},${str4}")
  }
}

object ScalaChild {
  def main(args: Array[String]): Unit = {
    val child = new ScalaChild()
    child.printInfo1
    child.printInfo2
  }
}

多態

咱們先看看比較熟悉的java。
定義了一個抽象類JavaAnimal,包含一個變量name和方法eat。JavaCat和JavaDog是JavaAnimal的實現類。在main方法中經過eat方法打印。scala

public abstract class JavaAnimal {
    public String name = "無";

    abstract void eat();
}

public class JavaCat extends JavaAnimal {
    String name = "小貓";

    void eat() {
        System.out.println("吃魚");
    }
}

public class JavaDog extends JavaAnimal {
    String name = "小狗";

    void eat() {
        System.out.println("吃骨頭");
    }
}

public class JavaAnimalMain {
    public static void eat(JavaAnimal animal) {
        System.out.println(animal.name);
        animal.eat();
    }

    public static void main(String[] args) {
        eat(new JavaCat());
        eat(new JavaDog());
    }
}

打印結果爲:code

無
吃魚
無
吃骨頭

能夠看到name爲父類的值,可是方法倒是調用子類的方法。
在scala中,實現相似的功能:繼承

abstract class ScalaAnimal {
  var name: String = "無"

  def eat(): Unit
}

object ScalaAnimal {
  def eat(animal: ScalaAnimal): Unit = {
    println("******")
    println(animal.name)
    animal.eat()
  }

  def main(args: Array[String]): Unit = {
    eat(new ScalaCat)
    eat(new ScalaDog)
  }
}

class ScalaCat extends ScalaAnimal {
  name = "小貓"

  override def eat(): Unit = {
    println("吃魚")
  }
}

class ScalaDog extends ScalaAnimal {
  name = "小狗"

  override def eat(): Unit = {
    println("吃骨頭")
  }
}

打印結果:it

******
小貓
吃魚
******
小狗
吃骨頭

name打印的是子類的name。
因此java中屬性是靜態綁定,方法是動態綁定。而scala中,屬性和方法都是動態綁定。class

相關文章
相關標籤/搜索