Scala 的类大抵和 Java 是类似的,简单的例子如下:

  1. class MyClass {
  2. var myField : Int = 0;
  3.  
  4. def this(value : Int) = {
  5. this();
  6. this.myField = value;
  7. }
  8.  
  9. def getMyField() : Int = {
  10. return this.myField;
  11. }
  12.  
  13. def addToMyField(value : Int) {
  14. this.myField += value;
  15. }
  16. }

如果好奇,可以把编译后的代码反编译成Java代码看看:

  1. import scala.reflect.ScalaSignature;
  2.  
  3. @ScalaSignature(bytes="\006\00112A!\001\002\001\013\t9Q*_\"mCN\034(\"A\002\002\017q*W\016\035;z}\r\0011C\001\001\007!\t9!\"D\001\t\025\005I\021!B:dC2\f\027BA\006\t\005\031\te.\037*fM\")Q\002\001C\001\035\0051A(\0338jiz\"\022a\004\t\003!\001i\021A\001\005\b%\001\001\r\021\"\001\024\003\035i\027PR5fY\022,\022\001\006\t\003\017UI!A\006\005\003\007%sG\017C\004\031\001\001\007I\021A\r\002\0275Lh)[3mI~#S-\035\013\0035u\001\"aB\016\n\005qA!\001B+oSRDqAH\f\002\002\003\007A#A\002yIEBa\001\t\001!B\023!\022\001C7z\r&,G\016\032\021\t\0135\001A\021\001\022\025\005=\031\003\"\002\023\"\001\004!\022!\002<bYV,\007\"\002\024\001\t\0039\023AC4fi6Kh)[3mIR\tA\003C\003*\001\021\005!&\001\007bI\022$v.T=GS\026dG\r\006\002\033W!)A\005\013a\001)\001")
  4. public class MyClass
  5. {
  6. private int myField = 0;
  7.  
  8. public int myField() { return this.myField; }
  9. public void myField_$eq(int x$1) { this.myField = x$1; }
  10.  
  11. public int getMyField()
  12. {
  13. return myField();
  14. }
  15.  
  16. public void addToMyField(int value) {
  17. myField_$eq(myField() + value);
  18. }
  19.  
  20. public MyClass()
  21. {
  22. }
  23.  
  24. public MyClass(int value)
  25. {
  26. this();
  27. myField_$eq(value);
  28. }
  29. }

除了ScalaSignature,其他部分再熟悉不过了。只是Scala在语法上稍作了改变,在学习了golang和swift之后,也应该习以为常了吧。

类部分虽然没有太多可说的地方,但是在对象上就有些许不同。Scala 中 object 用于构建 singleton 类型。

  1. object Main {
  2. def sayHi() {
  3. println("Hi!");
  4. }
  5. }

在 Java 进行调用的话,就是

  1. Main.sayHi();

之前在Java中写过Singleton代码的话,很容易猜出来具体的实现。反编译的代码:

  1. import scala.reflect.ScalaSignature;
  2.  
  3. @ScalaSignature(bytes="\006\001e9Q!\001\002\t\002\025\tA!T1j]*\t1!A\004=K6\004H/\037 \004\001A\021aaB\007\002\005\031)\001B\001E\001\023\t!Q*Y5o'\t9!\002\005\002\f\0355\tABC\001\016\003\025\0318-\0317b\023\tyAB\001\004B]f\024VM\032\005\006#\035!\tAE\001\007y%t\027\016\036 \025\003\025AQ\001F\004\005\002U\tQa]1z\021&$\022A\006\t\003\027]I!\001\007\007\003\tUs\027\016\036")
  4. public final class Main
  5. {
  6. public static void sayHi()
  7. {
  8. Main..MODULE$.sayHi();
  9. }
  10. }

实现上来讲,只是多了一个 Main$ 类来实现具体的代码。

有了静态成员,如何添加非静态成员?Scala给出的答案是 Companion Objects,也就是定义同名 class。

  1. object Main {
  2. def sayHi() {
  3. println("Hi!");
  4. }
  5. }
  6.  
  7. class Main {
  8. def sayHelloWorld() {
  9. println("Hello World");
  10. }
  11. }

这样一来,Main既支持静态方式调用,也支持实例化。其实在 Java 中只是一个类,包含了静态成员和非静态成员而已。  

  1. public class Main
  2. {
  3. public static void sayHi()
  4. {
  5. Main..MODULE$.sayHi();
  6. }
  7.  
  8. public void sayHelloWorld()
  9. {
  10. Predef..MODULE$.println("Hello World");
  11. }
  12. }

可以考虑一种情况,object 和 class 中都定义了相同名称的成员,结果会如何呢?

  1. object Main {
  2. def sayHi() {
  3. println("Hi!");
  4. }
  5. }
  6.  
  7. class Main {
  8. def sayHelloWorld() {
  9. println("Hello World");
  10. }
  11.  
  12. def sayHi() {
  13. println("non-static hi!")
  14. }
  15. }

编译没有报错,结果是静态成员无法访问了。

 

  1. error: non-static method sayHi() cannot be referenced from a static context
  2. Main.sayHi();
  3. ^
  4. 1 error

静态方法被隐藏了,可以通过反编译来验证。

  1. public class Main
  2. {
  3. public void sayHelloWorld()
  4. {
  5. Predef..MODULE$.println("Hello World");
  6. }
  7.  
  8. public void sayHi() {
  9. Predef..MODULE$.println("non-static hi!");
  10. }
  11. }

实际生成的代码中并不包含静态成员。有没有办法访问之前的静态成员呢?可以试试下面的代码:  

  1. Main$.MODULE$.sayHi();

当然,以上是Java中调用的情况,在 Scala 中是可以区分两个sayHi的。

  1. object UseInScala {
  2. def main(args: Array[String]) {
  3. Main.sayHi();
  4. var main = new Main();
  5. main.sayHi();
  6. }
  7. }

  输出:

  1. > scala UseInScala
  2. Hi!
  3. non-static hi!

  

从这些方面来看,Scala 的代码是极容易引入到 Java 中的,下一步可能会花些功夫在 Scala 的学习和应用上。

[1]http://tutorials.jenkov.com/scala/singleton-and-companion-objects.html

Scala 学习笔记(2)之类和对象的更多相关文章

  1. scala 学习笔记十 一 伴生对象

    1.介绍 a.所谓伴生对象就是和某个class同名的object, 并且object 必须和class在同一个scala源文件中. b.在scala中,没有像java中的静态类,静态方法和静态成员等, ...

  2. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  3. Scala学习笔记及与Java不同之处总结-从Java开发者角度

    Scala与Java具有很多相似之处,但又有很多不同.这里主要从一个Java开发者的角度,总结在使用Scala的过程中所面临的一些思维转变. 这里仅仅是总结了部分两种语言在开发过程中的不同,以后会陆续 ...

  4. Java学习笔记之---类和对象

    Java学习笔记之---类和对象 (一)类 类是一个模板,它描述一类对象的行为和状态  例如:动物类是一个类,动物们都有属性:颜色,动物们都有行为:吃饭 public class Dog { Stri ...

  5. Scala学习笔记之伴生对象

    所谓伴生对象, 也是一个Scala中的单例对象, 使用object关键字修饰. 除此之外, 还有一个使用class关键字定义的同名类, 这个类和单例对象存在于同一个文件中, 这个类就叫做这个单例对象的 ...

  6. Scala学习笔记(五):类和对象

    对象实例的变量组成了对象的内存映射 public是Scala的默认访问级别 Scala里方法参数的一个重要特征是它们都是val,不是var Scala不能定义静态成员 单例对象(singleton o ...

  7. 【大数据】Scala学习笔记

    第 1 章 scala的概述1 1.1 学习sdala的原因 1 1.2 Scala语言诞生小故事 1 1.3 Scala 和 Java  以及 jvm 的关系分析图 2 1.4 Scala语言的特点 ...

  8. Scala学习笔记之:tuple、array、Map

    [TOC] 本文<快学Scala>的笔记 tuple学习笔记 tuple的定义 对偶是元组(tuple)的最简单形态--元组是不同类型的值的聚集. 元组的值是通过将单个值包含在圆括号中构成 ...

  9. [原创]java WEB学习笔记15:域对象的属性操作(pageContext,request,session,application) 及 请求的重定向和转发

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  10. Scala学习笔记之二--基本数据类型

    前言 本篇主要讲Scala的基本数据类型,更多教程请参考:Scala教程 基本数据类型 Scala一共提供了9中数据类型,Scala的基本数据类型与java中的基本数据类型是一一对应的,这是Scala ...

随机推荐

  1. Python【知识点】傻傻的函数内变量

    问题的由来 有个学生问我一个问题关于函数内部变量的我们来一起看下代码: Code1 x = 50 def func(): print(x) global x print("x修改前的值:&q ...

  2. Ubuntu 16.04搭建LAMP开发环境

    基本设置 1.配置网络环境 管理员给分配了一个静态IP,所以还需要进一步配置网络环境 配置DNS:右上角网络连接->编辑链接->有线连接1->IPv4设置->DNS服务器:20 ...

  3. Nginx多进程高并发、低时延、高可靠机制缓存代理中的应用

    1. 开发背景 现有开源缓存代理中间件有twemproxy.codis等,其中twemproxy为单进程单线程模型,只支持memcache单机版和redis单机版,都不支持集群版功能. 由于twemp ...

  4. 解题:CF1130E Wrong Answer

    题面 巧妙构造题 这种题一定要限制一个条件,使得在这个条件下能推出要叉的代码的式子 令序列$a$的第一个元素为负,其余元素为正,且保证序列中至少有两个元素,那么Alice的代码将会从第二个元素开始计算 ...

  5. 【疑点】js中的break,continue和return到底怎么用?

    转: [疑点]js中的break,continue和return到底怎么用? 为什么要说个?好像很简单,但是我也会迷糊,不懂有时候为什么要用return,然而break和continue也经常和他放在 ...

  6. Json对象和Json字符串的区别

    说白了,字符串都是带引号的. 尤其是在使用springmvc的时候,后台@RequestBody接受的是一个json格式的字符串,一定是一个字符串.  参考这个博客还可以: https://blog. ...

  7. faster rcnn 详解

    转自:https://zhuanlan.zhihu.com/p/31426458 经过R-CNN和Fast RCNN的积淀,Ross B. Girshick在2016年提出了新的Faster RCNN ...

  8. 用yaml来编写配置文件

    yaml是一个数据序列化的标准,适用于所有开发语言,最大的特点是可读性好. yaml的一个主要应用方向就是编写配置文件,有非常多的系统和框架采用yaml进行配置. yaml有以下基本规则: 1.大小写 ...

  9. 支付宝APP支付,提示代码 ALIN10070

    ALIN10070 此代码时ALI64代码拆分后的细分代码: 代表签名验证失败等相关问题: 如果近期修改过或者续签 过签约协议,也需要更新公私钥.

  10. 集成maven和Spring boot的profile功能

    思路:maven支持profile功能,当使用maven profile打包时,可以打包指定目录和指定文件,且可以修改文件中的变量.spring boot也支持profile功能,只要在applica ...