zoukankan      html  css  js  c++  java
  • Scala学习随笔——深入类和对象

    函数化对象(又称方程化对象)指的是所定义的类或对象不包含任何可以修改的状态。

    本篇随笔就是着重记录函数化对象。定义了一个有理数类定义的几个不同版本,以介绍 Scala 类定义的几个特性:类参数和构造函数,方法,操作符,私有成员,重载,过载,条件检查,引用自身。

    一、Rational类的定义

      Rational类定义一个有理数。一个有理数可以表示为n/d,其中n、d都是整数(d != 0)。与浮点数相比,有理数可以精确的表示一个分数,而不会有误差。

    二、定义Rational

      Rational类暂定义如下:

    class Rational(n:Int, d:Int){
            println("Rational " + n + "/" + d)       
    }
    

      从上面的定义可以看出,与 Java 不同的是,Scala 的类定义可以有参数,称为类参数。

           Scala处理使用类参数外,还把类定义和主构造函数合并在一起,在定义类的同时也定义了类的主构造函数。

           Scala类的主构造函数是指类中任何不属于类成员和类方法的其他代码,Scala编译器会编译这个代码。

    三、重新定义类的toString方法

           重新定义类的方法时需要使用关键字——override——修饰。

           重新定义方法toString的代码如下:

    class  Rational(n:Int, d:Int){
           override  def  toString = n + "/" + d
    }
    

      如果不重新定义toString方法,就是缺省实现println(new Rational(3, 2) 打印出来对象的类名称+@+16进制数。

    四、前提条件检查

           当类的创建有先决条件时,例如有理数的分母不能为0,Scala中可以使用require方法。加入前提条件检查后的代码如下:

    class  Rational(n:Int, d:Int){
          require(d != 0)
           override  def  toString = n + "/" + d
    }
    

    五、添加成员变量

           尽管类参数在新定义的函数的访问范围之内,但仅限于定义类的方法本身(比如之前定义的 toString 方法,可以直接访问类参数),但对于 that 来说,无法使用 that.d 来访问 d 。

           这时候可以使用类的成员变量,添加成员变量之后的代码如下:

    class  Rational(n:Int, d:Int){
           require(d != 0)
    
           val  number = n
           val  denom = d
    
           override  def  toString = n + "/" + d
    
           def  add(that:Rational) = new  Rational
                         (number * that.denom + that.number * denom, denom * that.denom)
    }
    

           上述代码中添加了一个方法 add,实现两个Rational对象相加。

    六、自身引用

           可以使用this来引用当前对象的本身,这点与Java相同。一般来说访问类成员时无需使用this;如果需要引用对象本身则this不能shenglve。

           第一种:

    def lessThan(that:Rational) =
    this.number * that.denom < that.number * this.denom

           第二种:

    def lessThan(that:Rational) =
                 number * that.denom < that.number * denom
    def max(that:Rational) =
                 if(lessThan(that)) that else this
    

      

    七、辅助构造函数

           又称从构造函数,指除主构造函数之外的构造函数。

           所有 Scala 的辅助构造函数的第一个语句都为调用其它构造函数,也就是 this(…) 。被调用的构造函数可以是主构造函数或是其它构造函数(最终会调用主构造函数)。这样使得每个构造函数最终都会调用主构造函数,从而使得主构造函数称为创建类单一入口点。

           在 Scala 中也只有主构造函数才能调用基类的构造函数,这种限制有它的优点,使得 Scala 构造函数更加简洁和提高一致性。

           下面的代码定义了一个从构造函数,用来初始化分母为1的有理数,代码如下:

    class  Rational(n:Int, d:Int){
           require(d != 0)
    
           val  number = n
           val  denom = d
    
           override  def  toString = n + "/" + d
    
           def  this(n:Int) = this(n, 1)
    
           def  add(that:Rational) = new  Rational
                         (number * that.denom + that.number * denom, denom * that.denom)
    }
    

    八、私有成员变量和方法

            Scala中定义私用成员变量和方法使用private修饰。下面的代码为增加了一个私有成员变量和一个私用方法,求最大公约数。代码如下:

    class Rational (n:Int, d:Int) {
        require(d!=0)
    
        private val g =gcd (n.abs,d.abs) 
    
        val number =n/g 
        val denom =d/g 
        override def toString = number + "/" +denom
        def add(that:Rational)  = 
          new Rational( number * that.denom + that.number* denom,  denom * that.denom) 
    
        def this(n:Int) = this(n,1) 
    
        private def gcd(a:Int,b:Int):Int =
          if(b==0) a else gcd(b, a % b)
    }
    

      

    九、定义运算符

           在Scala中运算符(操作符)和普通方法没有什么区别,任何方法都可以写成操作符的方法。 例如 new Rational(3,2) add new Rational(5,2)是可以正确执行的。除此之外,也可以将方法add写成方法+,代码如下:

    class  Rational(n:Int, d:Int){
           require(d != 0)
    
           val  number = n
           val  denom = d
    
           override  def  toString = n + "/" + d
    
           def  +(that:Rational) = new  Rational
                         (number * that.denom + that.number * denom, denom * that.denom)
    }
    

      

    十、Scala中的标识符

           Scala 可以使用两种形式的标志符,字符数字和符号。字符数字使用字母或是下划线开头,后面可以接字母或是数字,符号 $ 在 Scala 中也看作为字母。然而以 $ 开头的标识符为保留的Scala编译器产生的标志符使用,应用程序应该避免使用 $ 开始的标识符,以免造成冲突。(解析公式失败)

           Scala 的命名规则采用和 Java 类似的 camel 命名规则(驼峰命名法),首字符小写,比如 toString 。类名的首字符还是使用大写。此外也应该避免使用以下划线结尾的标志符以避免冲突。

    十一、方法重载

           重载的方法参数类型不同而使用同样的方法名称。

    def  +(i:Int) = new Rational(number + i * denom, denom)
    

      例如在Rational类中加入上面的代码,就是对方法+的重载。

    十二、隐式类型转换

           new Rational(3, 2) + 2 可以计算出正确的结果,但是 2 + new Rational(3, 2) 就会出错。这是因为 2 是整型,不能自动转换成Rational类型,Scala中提供的隐式类型转换可以实现这种操作。

           定义一个隐式类型转换使用关键词 implicit  def.

           Int型隐式转换成Rational类型的方法代码如下:

    implicit  def  intToRational(x:Int) = new Rational(x)
  • 相关阅读:
    【Nginx+Tomcat】高性能负载均衡的Tomcat集群
    【JS-Excel】使用JS导出表格数据、附带解决科学计数法等问题
    【Util】日期工具类总结
    【SpringMVC】url映射传参
    【Linux+Windows】Linux,Windows打包发布到Tomcat并修改映射的ip地址
    【Spring】解决返回json乱码问题
    【API】高德地图API JS实现获取坐标和回显点标记
    ELK-Python(二)
    ELK-Python(一)
    zookeeper集群
  • 原文地址:https://www.cnblogs.com/aston/p/8782952.html
Copyright © 2011-2022 走看看