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)
    
  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/chenshaowei/p/13123916.html
Copyright © 2011-2022 走看看