• 函数式对象(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_Sql_打怪升级_进阶篇_进阶1:基础查询
    [20210218]shared latch spin count 5.txt
    springboot逻辑删除
    springboot整合mybatis-plus的两种分页查询方式--自定义的结果集分页返回浏览器
    spring图片上传并返回绝对路径
    springboot+mybatisplus 逻辑删除
    mybatisplus枚举类
    Could not find resource com/meng/dao/UserMapper.xml
    jsp页面表单提交后mysql未更新原因
    springMVC拦截器的使用
  • 原文地址:https://www.cnblogs.com/chenshaowei/p/13123916.html
Copyright © 2020-2023  润新知