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当中的继承的更多相关文章

  1. scala当中的类型参数

    类型参数主要就是研究scala当中的类或者scala当中的方法的泛型 1.scala当中的类的泛型         object Demo8 {          def main(args: Arr ...

  2. scala当中的对象

    1.scala当中的Object 在scala当中,没有类似于像java当中的static修饰的静态属性或者静态方法或者静态代码块之类的,但是我们可以通过scala当中的Object来实现类似的功能. ...

  3. Scala的类继承

    Scala的类继承 extend Scala扩展类的方式和java一样使用extends关键字 class Employee extends Person { } 与java一样,可以在定义的子类重写 ...

  4. scala当中的文件操作和网络请求

    1.读取文件当中每一行的数据 def main(args: Array[String]): Unit = { //注意文件的编码格式,如果编码格式不对,那么读取报错 val file: Buffere ...

  5. scala当中的类

    1.类的定义与创建 创建一个scala class来定义我们的一个类.类当中可以定义各种属性或者方法,或者函数都可以     class Person {       //定义一个属性,叫做name的 ...

  6. scala 面向对象之 继承

    scala 面向对象之 继承 scala   1.extends Scala中,让子类继承父类,与Java一样,也是使用extends关键字 继承就代表,子类可以从父类继承父类的field和metho ...

  7. scala当中的Actor并发编程

    注:Scala Actor是scala 2.10.x版本及以前版本的Actor. Scala在2.11.x版本中将Akka加入其中,作为其默认的Actor,老版本的Actor已经废弃. 1.什么是Sc ...

  8. SCALA中类的继承

    慢慢的,回想起以前学习JAVA和C#当中的的类的特性了. 感觉大同小异吧... package com.hengheng.scala class OOPInScala { } class Studen ...

  9. Scala数据类型的继承结构

    Scala中,所有的值都是类对象,而所有的类,包括值类型,都最终继承自一个统一的根类型Any.统一类型,是Scala的又一大特点.更特别的是,Scala中还定义了几个底层类(Bottom Class) ...

随机推荐

  1. HDU 5444 Elven Postman (2015 ACM/ICPC Asia Regional Changchun Online)

    Elven Postman Elves are very peculiar creatures. As we all know, they can live for a very long time ...

  2. redis数据类型(四)list类型

    一.list类型 list是一个链表结构,可以理解为一个每个子元素都是 string 类型的双向链表. 主要功能是push.pop.获取一个范围的所有值等. 操作中key理解为链表的名字. 二.Lis ...

  3. 屏幕置顶(WindowManager服务)

    https://www.cnblogs.com/mythou/p/3244208.html

  4. ansible api常用模块与参数

    ###ansibleAPI 常用模块 用于读取yaml,json格式的文件 from ansible.parsing.dataloader import DataLoader #用于管理变量的类,包括 ...

  5. IOS runtime动态运行时一

    对运行时不太了解,今天小伙伴橄榄油陈高给发了个链接 ,看了一部分先存着以后慢慢品 http://www.cocoachina.com/ios/20141018/9960.html http://blo ...

  6. laravel5.4学习--laravel安装

    1.使用Laravel HomeStead可以直接作为laravel的环境,如果没有使用Homestead,就必须保证开发环境满足以下要求 PHP版本 >= 5.6.4PHP扩展:OpenSSL ...

  7. Entity FreamWork框架

    实体框架 (Entity Framework) 1.是微软以ADO.Net为基础所发展出来的对象关系对应(O/R Mapping)解决方案. 2.实体框架Entity Framework是ADO.Ne ...

  8. 最大子序列和问题--时间复杂度O(NlogN)

    最大子序列和问题--时间复杂度O(NlogN) package a; /* * 最大子序列和问题,时间复杂度O(NlogN) */ public class Sequence { private st ...

  9. 基于.Net下整合IBatis

    一. 准备工作 1. 点击此下载支持.Net4.0的 iBatis.Net,工程中引用release文件夹下的dll 最新版(目前已不再更新),有稍作修改使其支持.NET4.0 2. 点击此可查看 i ...

  10. cookie、session、分页

    一.cookie HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情 ...