《快学Scala》第八章——继承
Posted lyq-biu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《快学Scala》第八章——继承相关的知识,希望对你有一定的参考价值。
一.本章要点
- extends,final关键字和Java一样
- 重写方法时必须使用override
- 只有主构造器可以调用超类的构造器
- 可以重写字段
二.扩展类
Scala扩展类和Java一样(使用extends关键字),也可以将类声明为final让它不能被扩展,也可以将单个方法或字段声明为final,确保不能重写。
注:Java中final是不可变的(相当于Scala中的val),但是Scala中是不能被扩展
三.重写方法
使用override修饰符:
public class Person{ override def toString=.... }
override的作用在多个常见情况下给出有用的错误提示,如:
-
-
- 拼错重写的方法名
- 在新方法中使用了错误的参数类型
- 在超类中引用新的方法,但是这个方法与子类方法相抵触(易违约基类问题,超类的修改无法在不检查所有子类的前提下被验证)
-
在Scala中调用超类的方法和Java完全一样,使用super关键字
四.类型检查和转换
isInstanceOf:测试某个对象是否属于某个给定的类,可以用isInstanceOf方法,如果为true就可以用asInstanceOf方法将引用转换为子类的引用。
例:
//如果p指向的是Employee类及其子类(比如Manager)的对象,则p.isInstanceOf[Employee]将会成功。 //如果p是null,则p.isInstanceOf[Employee]返回false,p.asInstanceOf[Employee]将返回null //如果p不是一个Employee,则p.asInstanceOf[Employee]将抛出异常 if(p.isInstanceOf[Employee]){ val s=p.asInstanceOf[Employee] }
classOf(在scala.Predef中,可以自动导入):测试某个对象是某个类的对象但又不是其子类。
例:
if(p.getClass==classOf[Employee])
五.受保护字段和方法
将字段或方法声明为protected,这样的成员可以被任何子类访问,但不能从其他位置看到。
注:与Java不同,protected的成员对于类所属的包而言,是不可见的;
Scala还停工了protected[this]的变体,把访问权限限定在当前的对象
六.超类的构造
辅助构造器永远不可能直接调用超类的构造器,子类的辅助构造器最终都会调用主构造器,只有主构造器可以调用超类的构造器。
主类构造器和类定义交织在一起,调用超类构造器也是交织在一起。
例:
//Employee类的三个参数有两个传递给了超类 class employee(name:String,age:Int,val salary:Double) extends Person(name,age)
注:在Scala构造器中,不能调用super(params)[Java可以]
Scala可以扩展Java类,这种情况必须调用Java类的某一个构造方法
七.重写字段
子类可以重写父类的字段。
注:
-
-
- def只能重写另一个def
- val只能重写另一个val或不带参数的def
- val只能重写另一个抽象的var
-
八.匿名子类
和Java一样,可以通过包含带有定义或重写代码块的方式创建一个匿名的子类,例:
//这会创建一个结构类型的对象,可以作为参数类型的定义 val alien=new Person("Fred"){ def greeting="xxxxxxx" } def meet(p:Person(def greeting:String)){}
九.抽象类
和Java一样,可以用abstract关键字标记不能被实例化的类(通常因为某个或某几个方法没有被完整定义)。
例:
abstract class Employee(val name:String){ def id:Int //没有方法体——抽象方法 }
注:
Scala中抽象方法不用使用abstract关键字,只需省略方法体就行;
只要类中有一个抽象方法,这个类就需要是抽象类,类必须声明abstract;
子类中重写超类的抽象方法时不需要使用override关键字
十.抽象字段
即没有初始值的字段。
例:
abstract class Person{ val id:Int //没有初始化——带有抽象的getter方法的抽象字段 var name:String //带有抽象的getter和setter方法 }
注:子类必须提供具体的字段;
子类重写超类的字段不需要使用override
//具体的id和name属性 class Employee(var id:Int) extends Person{ var name="" } //通过匿名类型定制抽象字段 val fred=new Person{ val id=1 val name="Fred" }
十一.构造顺序和提前定义
十二.Scala继承等级
十三.对象相等性
以上是关于《快学Scala》第八章——继承的主要内容,如果未能解决你的问题,请参考以下文章