zoukankan      html  css  js  c++  java
  • 【scala】类的定义和单例对象

    一、类的定义

      Scala类的定义跟JAVA中类的定义基本是一样的。

    示例

    class ChecksumAccumulator{
        var sum = 0;//Scala默认关键字为public
        private var sum = 0;
        def add(b : Byte) : Unit ={
             sum+=b;
        }     
        def checkSum() : Int = {
              return ~(sum & 0xFF) + 1;
        }  
    }

      Scala中,当一个方法只会计算一个返回结果的表达式时,可以不用写花括号。

      Scala中,在没有任何显式的return语句时,返回的是该方法计算出的最后一个表达式的值。

      所以上述代码可以简化成

    class ChecksumAccumulator{
        private var sum = 0;
        def add(b:Byte) = sum+=b;
        def checkSum() = ~(sum & 0xFF) +1;
    }

    二、单例对象

      Scala比Java更面向对象的一点,是Scala的类不允许有静态(static)成员。

      对此类使用场景,Scala提供了单例对象。

      我们可以把单例对象当作java的静态方法。但是,单例对象并不仅仅是用来存放静态方法,它是一等对象,可以想象成附加在对象身上的名字标签。

      我们调用单例对象的方法同调用java静态方法是一样的,单例对象名.方法名

      表面上 看上去单例对象的定义跟类的定义很像,只不过是class关键字换成了object关键字。

    import scala.colletion.mutable
    
    object ChecksumAccumulator{
        private val cache = mutable.Map,empty[String,Int];
        def calculate(s:String) : Int = 
               if(cache.contains(s))
                  cache(s);
               else{
                   val acc = new ChecksumAccumulator;
                   for(c <- s)
                      acc.add(c.toByte);
                   val cs = acc.checkSum();
                   cache += (s -> cs);//将(s,cs)加入cache
                   cs;//这里省略了return 
               }  
    
    }

      上面代码是一个单例对象,我们注意到这个单例对象的名字跟上面类的名字相同 ,这样的单例对象成为这个类的伴生对象,反过来,这个类被成为这个对象的半生类。

      伴生类和伴生对象必须同在一个源码文件中,他们可以相互访问对方的私有成员。

      没有同名的伴生类的单利对象成为孤立对象。

      孤立对象有很多用途,例如将工具方法归集在一起,定义Scala应用程序的入口等。

    三、类和单例对象的区别

      单例对象不接受参数,而类可以。

      由于没法用new实例化单例对象,也就没有任何手段来向它传参。

      每个单例对象都是通过一个静态变量引用合成类的实例来实现的,因此单例对象从初始花的语义上跟java静态成员是一致的。

      体现在单例对象在有代码首次访问时才能被初始化。

    示例

    class Person{
        //类和伴生对象可以相互访问彼此的私有属性
        private var id = Person.newLastId(); //调用了伴生对象的私有方法
        private var name = "";
        def this(name:String){
            this();
            this.name = name;
        }
        def info(): Unit ={
            println(name+"id is "+"id");
        }
    }
    object Person{
        //scala对象相当于java中的static类
        //定义在对象中的字段或者方法也是具有static特性的,可以直接拿来用不用new
        private var lastId = 0;//这个字段是静态的
        private def newLastId() ={
            lastId += 1;
            lastId;
        }
        def main(args:Array[String]): Unit ={
            val person1 = new Person("zhangyuhang");
            //建立Person类,类再调用半生对象的newLastId
            val person2 = new Person("zhangqiuyue");
            person1.info();
            person2.info();
        }
    }  
    运行结果
    zhangyuhangid is 1

    zhangqiuyueid is 2

     结果分析,因为定义在object中的字段和方法都是静态的。

     newLastId方法定义在object中为静态方法,可以直接调用。

       我们在每次调用newLastId方法的时候,因为IastId是静态字段所以都在原有基础上+1.

     尽管是不同对象调用的也如此。

  • 相关阅读:
    C#和JAVA的RSA密钥、公钥转换
    JAVA RSA私钥 加密(签名) 对应 C# RSA私钥 加密(签名)
    Senparc.Weixin.MP SDK 微信公众平台开发教程(九):自定义菜单接口说明
    微信资料
    OAuth2.0实战之微信授权篇
    URL中出现了%E2%80%8E(Zero-Width Space)
    AntDesign vue学习笔记(六)Table 显示图片
    NPOI导出 The maximum column width for an individual cell is 255 characters
    AntDesign vue学习笔记(五)导航菜单动态加载
    AntDesign vue学习笔记(四)使用组件切换
  • 原文地址:https://www.cnblogs.com/zzhangyuhang/p/8666152.html
Copyright © 2011-2022 走看看