Scala - 抽象、继承、多态

抽象 scala的抽象关键字和java一样,都是abstract,而且抽象类都不能被实例化的。
除了类可以定义为抽象的,类的属性和方法,也可以是抽象的。
从下面的例子中,可以看到其实和java的抽象类定义没有什么区别

abstract class ScalaAbstract { // 抽象属性,可以没有初始值,甚至不用_ var str1: String var str2: String = "str2" val str3: String val str4: String = "str4"/** * 抽象方法 */ def printInfo1: Unitdef 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("吃骨头") } }

打印结果:
****** 小猫 吃鱼 ****** 小狗 吃骨头

【Scala - 抽象、继承、多态】name打印的是子类的name。
所以java中属性是静态绑定,方法是动态绑定。而scala中,属性和方法都是动态绑定。

    推荐阅读