关于scala:Scala-抽象继承多态

2次阅读

共计 2020 个字符,预计需要花费 6 分钟才能阅读完成。

形象

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 中,属性和办法都是动静绑定。

正文完
 0