zoukankan      html  css  js  c++  java
  • 函数式对象(Scala)

    函数式对象

    以Rational类为例,以下介绍类参数、构造方法、方法、操作符、私有成员、重写、前置条件检查、重载以及自引用。

    不可变对象和可变对象的区别

    不可变对象通常比可变对象更容易推理,没有随着时间变化而变化,没有复杂的状态空间。其次,可以自由传递不可变对象。而对于可变对象,在传递之前,需要做保护式的拷贝。不可变对象可以安全地用作哈希表的键。
    劣势是不可变对象需要一个大的对象图。

    构造Rational类

    class Rational(n : Int, d : Int)
    

    可以发现和Java有所不同,其类就能接收参数。而在Java中得有构造方法,构造方法接收参数。

    重写实现toString方法

    可以通过给Rational类添加toString方法来重写默认的实现。

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

    检查前置条件

    对于不可变对象,要确保对象在构建时的合法性。比如有理数不能分母为0。当传入参数d为0时,应该禁止生成对象。
    解决这个问题是对主构造方法定义一个前置条件

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

    require方法接收一个boolean参数,传入true,正常返回,传入false,跑出IllegalArgumentException异常

    添加字段

    定义一个add方法,接收另一个Rational类,为了保持不可变特性,add方法必须创建另一个Rational类,等于这两个Rational类的和。

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

    不允许使用that.n和that.d来实现。要访问that的分子和分母,要把它们做成字段。

    构造方法

    某个类定义多个构造方法。在Scala中,主构造方法之外的构造方法称为辅助构造方法。
    比如Rational类只接收一个参数,即分子。分母被预定义为1.

    //使用this,即类的主构造方法。
    def this(n:Int) = this(n,1)
    

    私有字段和方法

    比如对Rational类做正规化,要分子和分母除以最大公约数。

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

    定义操作符

    将x.add(y)转为x+y。

    //加法
    def + (that: Rational):Rational = 
        new Rational(
            numer * that.denom + that.numer * denom,
                denom * that.denom
        )
    //乘法
    def * (that: Rational):Rational = 
        new Rational(
            numer * that.numer,
            denom * that.denom
        )
    

    方法重载

    以+为例,右操作元,可能是有理数,也有可能是整数

    def + (that: Rational):Rational = 
        new Rational(
            numer * that.denom + that.numer * denom,
                denom * that.denom
        )
    def + (i: Int) = 
        new Rational(numer + i * denom, denom)
    
  • 相关阅读:
    [记录]MySQL 查询无法导出到文件
    Unity3D 在Update中不要过多地修改Transform 信息
    Unity3D 中 脚本(MonoBehaviour) 生命周期WaitForEndOfFrame需要注意的地方
    RunTime的简单使用
    GIT命令行的使用
    UIImagePickerController和UIAlertController结合使用
    NSSortDescriptor对象进行数组排序
    for..in遍历,枚举器
    Objective
    Objective
  • 原文地址:https://www.cnblogs.com/chenshaowei/p/13123916.html
Copyright © 2011-2022 走看看