scala当中的继承
1、Scala中继承(extends)的概念
- Scala 中,让子类继承父类,与 Java 一样,也是使用 extends 关键字;
- 继承就代表,子类可继承父类的 field 和 method ,然后子类还可以在自己的内部实现父类没有的,子类特有的 field 和method,使用继承可以有效复用代码;
- 子类可以覆盖父类的 field 和 method,但是如果父类用 final 修饰,或者 field 和 method 用 final 修饰,则该类是无法被继承的,或者 field 和 method 是无法被覆盖的。
- private 修饰的 field 和 method 不可以被子类继承,只能在类的内部使用;
- field 必须要被定义成 val 的形式才能被继承,并且还要使用 override 关键字。 因为 var 修饰的 field 是可变的,在子类中可直接引用被赋值,不需要被继承;即 val 修饰的才允许被继承,var 修饰的只允许被引用。继承就是改变、覆盖的意思。
- Java 中的访问控制权限,同样适用于 Scala
|
类内部 |
本包 |
子类 |
外部包 |
public |
√ |
√ |
√ |
√ |
protected |
√ |
√ |
√ |
× |
default |
√ |
√ |
× |
× |
private |
√ |
× |
× |
× |
举例说明:
package com.starzy.extends_demo class Person { val name="super" def getName=this.name } class Student extends Person{ //继承加上关键字 override val name="sub" //子类可以定义自己的field和method val score="A" def getScore=this.score } |
2、Scala中override 和 super 关键字
- Scala中,如果子类要覆盖父类中的一个非抽象方法,必须要使用 override 关键字;子类可以覆盖父类的 val 修饰的field,只要在子类中使用 override 关键字即可。
- override 关键字可以帮助开发者尽早的发现代码中的错误,比如, override 修饰的父类方法的方法名拼写错误。
- 此外,在子类覆盖父类方法后,如果在子类中要调用父类中被覆盖的方法,则必须要使用 super 关键字,显示的指出要调用的父类方法。
举例说明:
class Person1 { private val name = "leo" val age=50 def getName = this.name } class Student1 extends Person1{ private val score = "A" //子类可以覆盖父类的 val field,使用override关键字 override val age=30 def getScore = this.score //覆盖父类非抽象方法,必须要使用 override 关键字 //同时调用父类的方法,使用super关键字 override def getName = "your name is " + super.getName } |
3、Scala中isInstanceOf 和 asInstanceOf
如果实例化了子类的对象,但是将其赋予了父类类型的变量,在后续的过程中,又需要将父类类型的变量转换为子类类型的变量,应该如何做?
- 首先,需要使用 isInstanceOf 判断对象是否为指定类的对象,如果是的话,则可以使用 asInstanceOf 将对象转换为指定类型;
- 注意: p.isInstanceOf[XX] 判断 p 是否为 XX 对象的实例;p.asInstanceOf[XX] 把 p 转换成 XX 对象的实例
- 注意:如果没有用 isInstanceOf 先判断对象是否为指定类的实例,就直接用 asInstanceOf 转换,则可能会抛出异常;
- 注意:如果对象是 null,则 isInstanceOf 一定返回 false, asInstanceOf 一定返回 null;
- Scala与Java类型检查和转换
Scala |
Java |
obj.isInstanceOf[C] |
obj instanceof C |
obj.asInstanceOf[C] |
(C)obj |
classOf[C] |
C.class |
举例说明:
class Person3 {} class Student3 extends Person3 object Student3{ def main (args: Array[String] ) { val p: Person3 = new Student3 var s: Student3 = null //如果对象是 null,则 isInstanceOf 一定返回 false println (s.isInstanceOf[Student3]) // 判断 p 是否为 Student3 对象的实例 if (p.isInstanceOf[Student3] ) { //把 p 转换成 Student3 对象的实例 s = p.asInstanceOf[Student3] } println (s.isInstanceOf[Student3] ) } } |
4、Scala中getClass 和 classOf
- isInstanceOf 只能判断出对象是否为指定类以及其子类的对象,而不能精确的判断出,对象就是指定类的对象;
- 如果要求精确地判断出对象就是指定类的对象,那么就只能使用 getClass 和 classOf 了;
- p.getClass 可以精确地获取对象的类,classOf[XX] 可以精确的获取类,然后使用 == 操作符即可判断;
举例说明:
class Person4 {} class Student4 extends Person4 object Student4{ def main(args: Array[String]) { val p:Person4=new Student4 //判断p是否为Person4类的实例 println(p.isInstanceOf[Person4])//true //判断p的类型是否为Person4类 println(p.getClass == classOf[Person4])//false //判断p的类型是否为Student4类 println(p.getClass == classOf[Student4])//true } } |
5、Scala中使用模式匹配进行类型判断
- 在实际的开发中,比如 spark 源码中,大量的地方使用了模式匹配的语法进行类型的判断,这种方式更加地简洁明了,而且代码的可维护性和可扩展性也非常高;
- 使用模式匹配,功能性上来说,与 isInstanceOf 的作用一样,主要判断是否为该类或其子类的对象即可,不是精准判断。
- 等同于 Java 中的 switch case 语法;
举例说明:
class Person5 {} class Student5 extends Person5 object Student5{ def main(args: Array[String]) { val p:Person5=new Student5 p match { // 匹配是否为Person类或其子类对象 case per:Person5 => println("This is a Person5's Object!") // 匹配所有剩余情况 case _ =>println("Unknown type!") } } } |
6、Scala中protected
- 跟 Java 一样,Scala 中同样可使用 protected 关键字来修饰 field 和 method。在子类中,可直接访问父类的 field 和 method,而不需要使用 super 关键字;
- 还可以使用 protected[this] 关键字, 访问权限的保护范围:只允许在当前子类中访问父类的 field 和 method,不允许通过其他子类对象访问父类的 field 和 method。
举例说明:
class Person6{ protected var name:String="tom" protected[this] var hobby:String ="game" protected def sayBye=println("再见...") } class Student6 extends Person6{ //父类使用protected 关键字来修饰 field可以直接访问 def sayHello =println("Hello "+name) //父类使用protected 关键字来修饰method可以直接访问 def sayByeBye=sayBye def makeFriends(s:Student6)={ println("My hobby is "+hobby+", your hobby is UnKnown") } } object Student6{ def main(args: Array[String]) { val s:Student6=new Student6 s.sayHello s.makeFriends(s) s.sayByeBye } } |
7、Scala中调用父类的constructor
- Scala中,每个类都可以有一个主constructor和任意多个辅助constructor,而且每个辅助constructor的第一行都必须调用其他辅助constructor或者主constructor代码;因此子类的辅助constructor是一定不可能直接调用父类的constructor的;
- 只能在子类的主constructor中调用父类的constructor。
- 如果父类的构造函数已经定义过的 field,比如name和age,子类再使用时,就不要用 val 或 var 来修饰了,否则会被认为,子类要覆盖父类的field,且要求一定要使用 override 关键字。
举例说明:
class Person7(val name:String,val age:Int){ var score :Double=0.0 var address:String="beijing" def this(name:String,score:Double)={ //每个辅助constructor的第一行都必须调用其他辅助constructor或者主constructor代码 //主constructor代码 this(name,30) this.score=score } //其他辅助constructor def this(name:String,address:String)={ this(name,100.0) this.address=address } } class Student7(name:String,score:Double) extends Person7(name,score) |
8、Scala中抽象类
- 如果在父类中,有某些方法无法立即实现,而需要依赖不同的子类来覆盖,重写实现不同的方法。此时,可以将父类中的这些方法编写成只含有方法签名,不含方法体的形式,这种形式就叫做抽象方法;
- 一个类中,如果含有一个抽象方法或抽象field,就必须使用abstract将类声明为抽象类,该类是不可以被实例化的;
- 在子类中覆盖抽象类的抽象方法时,可以不加override关键字;
举例说明:
abstract class Person9(val name:String) { //必须指出返回类型,不然默认返回为Unit def sayHello:String def sayBye:String } class Student9(name:String) extends Person9(name){ //必须指出返回类型,不然默认 def sayHello: String = "Hello,"+name def sayBye: String ="Bye,"+name } object Student9{ def main(args: Array[String]) { val s = new Student9("tom") println(s.sayHello) println(s.sayBye) } } |
9、Scala中抽象field
- 如果在父类中,定义了field,但是没有给出初始值,则此field为抽象field;
举例说明:
abstract class Person10 (val name:String){ //抽象fields val age:Int } class Student10(name: String) extends Person10(name) { val age: Int = 50 } |
scala当中的继承的更多相关文章
- scala当中的类型参数
类型参数主要就是研究scala当中的类或者scala当中的方法的泛型 1.scala当中的类的泛型 object Demo8 { def main(args: Arr ...
- scala当中的对象
1.scala当中的Object 在scala当中,没有类似于像java当中的static修饰的静态属性或者静态方法或者静态代码块之类的,但是我们可以通过scala当中的Object来实现类似的功能. ...
- Scala的类继承
Scala的类继承 extend Scala扩展类的方式和java一样使用extends关键字 class Employee extends Person { } 与java一样,可以在定义的子类重写 ...
- scala当中的文件操作和网络请求
1.读取文件当中每一行的数据 def main(args: Array[String]): Unit = { //注意文件的编码格式,如果编码格式不对,那么读取报错 val file: Buffere ...
- scala当中的类
1.类的定义与创建 创建一个scala class来定义我们的一个类.类当中可以定义各种属性或者方法,或者函数都可以 class Person { //定义一个属性,叫做name的 ...
- scala 面向对象之 继承
scala 面向对象之 继承 scala 1.extends Scala中,让子类继承父类,与Java一样,也是使用extends关键字 继承就代表,子类可以从父类继承父类的field和metho ...
- scala当中的Actor并发编程
注:Scala Actor是scala 2.10.x版本及以前版本的Actor. Scala在2.11.x版本中将Akka加入其中,作为其默认的Actor,老版本的Actor已经废弃. 1.什么是Sc ...
- SCALA中类的继承
慢慢的,回想起以前学习JAVA和C#当中的的类的特性了. 感觉大同小异吧... package com.hengheng.scala class OOPInScala { } class Studen ...
- Scala数据类型的继承结构
Scala中,所有的值都是类对象,而所有的类,包括值类型,都最终继承自一个统一的根类型Any.统一类型,是Scala的又一大特点.更特别的是,Scala中还定义了几个底层类(Bottom Class) ...
随机推荐
- 虚拟机安装Ubuntu的上网设置(有线网络和无线网络)
(恩,是转的) 虚拟机下ubuntu共享方式上网: 一. 有线网络 在有线网络的条件下,vmware的安装非常简单,上网方式几乎不用怎么设置(默认NAT模式) 如果默认情况下不能上网,则按以下 ...
- 【AppScan】入门工作原理详解
AppScan,即 AppScan standard edition.其安装在 Windows 操作系统上,可以对网站等 Web 应用进行自动化的应用安全扫描和测试.Rational AppScan( ...
- [转]OData and Authentication – Part 6 – Custom Basic Authentication
本文转自:https://blogs.msdn.microsoft.com/astoriateam/2010/07/21/odata-and-authentication-part-6-custom- ...
- PHP项目学习——控件
主要是在项目学习中总结的一些东西 动态效果 flashbar滚动条,增加动态效果,直接嵌入html中 <!--flash滚动条--> <object classid="cl ...
- git常用小操作。-- 自用
编辑 .gitignore bin-debug/ 忽略所有的叫bin-debug文件夹和他下面的文件 编辑 .git/config [core] repositoryformatversion = ...
- C# 泛型使用笔记
泛型的基本概念我就不在这重复了,不了解的同学请自行百度. 我主要写下我在项目中要到的泛型实例.献丑了.....有什么不好或不对的地方大家尽可评论留言. 为什么要用泛型? 通过使用泛型,我们可以极大地提 ...
- 经典的SQL面试题及答案
- java poi处理新版xlsx后缀的excel
jar包下载地址http://poi.apache.org/download.html#POI-3.17,我把下载文件中的所有jar包都导入项目中才能跑 参考以下博客 https://www.cnbl ...
- 基于easyUI实现经典系统主界面
此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 相关文件介绍 1. home.jsp:系统主界面 <!DOCTYPE html PUBLIC "-//W3C ...
- PAT 1032. Sharing
其实就是链表求交: #include <iostream> #include <cstdio> #include <cstdlib> #include <un ...