形象

scala的形象关键字和java一样,都是abstract,而且抽象类都不能被实例化的。
除了类能够定义为形象的,类的属性和办法,也能够是形象的。
从上面的例子中,能够看到其实和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的,包含先调用父类的结构器等。区别如下:

  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办法打印。

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());    }}

打印后果为:

无吃鱼无吃骨头

能够看到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("吃骨头")  }}

打印后果:

******小猫吃鱼******小狗吃骨头

name打印的是子类的name。
所以java中属性是动态绑定,办法是动静绑定。而scala中,属性和办法都是动静绑定。