zoukankan      html  css  js  c++  java
  • Programming In Scala笔记-第十一章、Scala中的类继承关系

      本章主要从整体层面了解Scala中的类层级关系。

    一、Scala的类层级

      在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类。在Scala中所有类的最终父类为Any类,所以Any类中的所有方法都可以在Scala中任意类中使用。但是这并不是说Scala中的Any类就类似于Java中的Object类,Scala中真正地位类似于Java中Object类的是AnyRef类。

      在Scala中还提供了两个类NullNothing,这两个类在整个Scala类层级的最底层,其中Nothing类是所有类的最终子类,Nothing类直接或间接继承其他任何类。

    1、整体类层级图

      下图展示了Scala中的整体类层级图,其中Any位于最顶端,Nothing位于最底端。
      这里写图片描述

    2、Any类结构

      这一节中我们看一下Any类中定义了哪些方法。
      从Scala API文档中可以看到,Any类中提供==, !=, equals, ##, hashCode, toString, isInstanceOf[TO], asInstanceOf[TO]共八个方法。其中==, !=, ##, asInstanceOf[TO], isInstanceOf[TO]final类型的,不能在子类中使用override关键字进行重写。在Scala中对于==方法,如果判断对象为引用类型,调用该方法等同于调用该对象的equals方法。
      
      Any类的两个直接子类是AnyValAnyRef,其中AnyVal是Scala中的值类型,比如Double, Float等的直接父类,注意这里Unit类型也是AnyVal类型的直接子类。而AnyRef则是Scala中所有引用类型类的父类,类似于Java中的Object类。
      

    二、原始类型是如何实现的

      对Java熟悉的话,应该会对int类型和Integer类型有一定的了解。在Scala中对Int类型变量的处理也和Java中类似,Int类型提供加或乘这样的简单操作,但如果需要调用toString方法或者将Int值赋给Any类型变量时,Int型变量会自动转化成Integer类型。这个过程和Java中的自动装箱有些类似。
      我们首先看一下下面这段Java代码

    boolean isEqualInt(int x, int y) {
      return x == y;
    }
    System.out.println(isEqual(421, 421));
    
    boolean isEqualInteger(Integer x, Integer y) {
      return x == y;
    }
    System.out.println(isEqualInteger(421, 421));

      代码在IDEA中的运行结果如下
      这里写图片描述

      isEqualInt方法接收到传入的两个整数后直接判断值是否相等,得到的结果为true。但是isEqualInteger方法接收到整型参数后,哪怕是值相等的整型参数,也会首先自动装箱成两个Integer类型对象,并且两个Integer对象是不同的对象,调用==方法得到的结果为false

      再看一段Scala中的代码,仍然定义两个函数、

    def isEqualInt(x: Int, y: Int) = x == y
    isEqualInt(421, 421)
    
    def isEqualAny(x: Any, y: Any) = x == y
    isEqualAny(421, 421)

      运行结果如下,
      这里写图片描述

      由于在Scala中,引用类型调用==方法等同于调用equals方法,所以isEqualAny方法的返回结果也是true

      那么,如果在Scala中就是需要判断两个引用类型对象的引用是否相等,应该怎么办?在AnyRef类中,Scala提供了eqne方法。

    val x = new String("abc")
    val y = new String("abc")
    
    x == y
    x eq y
    x ne y

      运行结果如下,
      这里写图片描述

    三、底层类型

      这里主要讨论上面的类继承关系图中最底层的两个类scala.Nullscala.Nothing。Scala中可以使用者两个类统一的处理一些面向对象编程的边界情况。

    1、Null类

      比如说在Java中,null值是没有对应的类型的,如果将某个变量赋值null然后调用getClass方法,会报一个NullPointerException,如下图所示。
      这里写图片描述

      但是在Scala中null值的类型为NullNull类型所有引用类型类的子类,而不是值类型的子类。所以,不能将null赋值给Int类型变量。

    val i: Int = null

      执行结果如下,
      这里写图片描述

    2、Nothing类

      Nothing类位于Scala类继承关系中的最底层,是Scala中任何类的子类,包括上面的Null类。
      由于Nothing类是任何类的子类,所以可以以如下形式来使用该类。

    def error(message: String): Nothing =
      throw new RuntimeException(message)
    
    def divide(x: Int, y: Int): Int =
      if (y != 0) x / y
      else error("can't divide by zero")

      在前面我们知道了,Scala中的执行语句都有一个返回结果类型,对于if语句来说,返回类型为两个分支的公共父类,而这里if分支的返回类型为IntIntelse的返回类型Nothing的父类,所以divide方法的最终返回类型仍然是Int

  • 相关阅读:
    观察者模式 java实现
    Decorator 模式
    Adapter 模式 java 实现
    Singleton 模式 Java,c++实现
    抽象工厂 java实现
    工厂方法模式 java实现
    简单工厂模式 Java实现
    【4】学习JS 数据结构与算法笔记
    【3】JavaScript编程全解笔记(三)
    【3】如何高效学习笔记
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300218.html
Copyright © 2011-2022 走看看