形象
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 的,包含先调用父类的结构器等。区别如下:
- 如果笼罩父类的非形象办法,非形象变量,在 scala 中要写 override,在 java 中只是正告。
- 形象办法,var 定义的形象变量,能够不写 override,也能够写。
- 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 中,属性和办法都是动静绑定。