Classes

  • 一个源文件可包含多个类,每个类默认都是 public
  • 类字段必须初始化,编译后默认是 private,自动生成 public 的 getter/setter ;Person 示例
    • private 字段,生成 private 的 getter/setter
    • val 字段,只生成 getter
    • private[this] 字段,不生成 getter/setter
    • 自定义 getter/setter,foo 和 foo_=
  • 类方法默认都是 public
  • 方法调用规约:访问器调用可省略括号,修改器调用加上括号
  • 为字段加上 @bean.BeanProperty 注解可生成符合 JavaBean 规范的 get/set 方法(加上默认的两个方法,共四个方法)
  • 构造器:1 个主构造器,任意个辅构造器
    • 全部都叫 this,只是参数不同
    • 辅构造器必须调用主构造器或之前定义的辅构造器
    • 主构造器与类定义密不可分,参数直接定义在类名后
    • 主构造器会立即执行类定义中的所有语句
    • 主构造器中的参数被方法使用到,则对应的参数等价于 private[this] val 字段
  • 内部类
    • 路径依赖,不同于 Java 内部类,同一类 A 的不同实例(a1, a2)构建的内部类 Inner,其类型是不同的,a1.Inner != a2.Inner
    • 解决路径依赖
      • 类型投射,Outer#Inner
      • 将内部类放到伴生对象 object 中
    • self => 自身类型,区分调用的内部类和外部类的字段、方法等

Objects

  • 用于单例及工具类方法

    • object 构造器只在第一次被调用时执行
  • 可继承一个 class 或多个 trait
    • 可用于全局默认对象
  • 不可提供构造器参数
  • 伴生对象
    • 与类名称一致
    • 类与伴生对象可互相访问私有资源,但区分作用域,如 Accounts.newUniqueNumber() 而不是 newUniqueNumber()
    • 类与伴生对象必须在同一个源文件中
  • 伴生对象中的 apply 方法
    • 调用方式 Object(arg1, ..., argN), 返回伴生类的实例,如 Array(1,2,3)
    • 省略 new 关键字,在嵌套表达式中很方便
  • 应用对象
    • extends App
    • 不需要 main 方法直接执行构造器内的代码
  • scala 默认无枚举类型
    • 使用 Enumeration 帮助类实现
    • 枚举类型为 Enumeration.Value(ID, name) 内部类, ID 依次累加, 默认 0 开始;name 默认是字段名

Traits

  • 替代 Java 中的接口
  • 可以有抽象的和具体的方法
    • trait 中未实现的方法默认是抽象的 (abstract)
  • 类可以实现多个 trait,从最后一个开始调用
    • 使用 extends 关键字实现
    • 覆盖抽象方法时不需要 override 关键字
    • 有多个 trait 则对其他的 trait 使用 with 关键字
  • 所有的 Java 接口都可以被当做 trait 使用
  • 对象也可以添加多个 trait,从最后一个开始调用
  • 多个 trait 的情况下,super.someMethod 会根据从右向左的顺序调用下一个 trait 的方法
    • 具体调用依赖于使用时的顺序,相比传统的继承更灵活
    • 在多个 mix-in 的情况下,如果父trait存在抽象方法,则子trait需使用 abstract override 关键字,否则 super.someMethod 无法编译
  • 有初始值的字段/具体字段,都会被添加到子类中
  • 无初始值的字段/抽象字段,在非抽象子类中,需要进行初始化
  • trait 也有构造器
    • 不可以有构造参数,且只有一个构造器
    • 由定义体中的初始化字段和其他语句构成
    • 构造顺序:父类 > 各trait从左向右,有父 trait 的先构造,共享的父 trait 只构造一次 > 子类
    • 考虑到构造顺序,如果子类中使用抽象字段,则可使用提前定义(early definition,会在构造器之前执行)的语法讲改字段初始化
      • 提前定义语句块中只能使用字段定义语句,不可使用其他语句
  • trait 可继承类,混入该 trait 的类都是被继承类的子类,子类如果有继承其他的类也必须是被继承类的子类
  • 与自身类型(self type)比较
    • trait 不继承类,直接在 body 内定义 this: Type =>,则混入的类必须是该 Type 类型的/子类型的
    • 也可使用结构类型(structural type),this: { def log(msg: String) } => ,则混入的类必须包含结构类型中定义的方法
  • trait 最终会翻译成类和接口

Packages and Imports

  • package 包名和文件路径并不一定对应
  • java.lang, scala, Predef 始终默认会导入
  • 与 Java 不同,包路径并不是绝对的,如 collection.mutable 实际是 scala.collection.mutable
  • package a.b.cpackage a { package b { package c {}}} 不同
    • package apackage b 中定义的资源可在带括号的包声明中访问,但 package a.b.c 无法访问
  • 包对象
    • package 由于 JVM 的限制不能直接声明函数或变量
    • 不同于 package, package object 可定义工具函数或常量
  • 可见性控制,通过 private[package.name] 限制资源的可见性
  • import
    • 导入包后可使用相对路径访问类等,如 collection.mutable
    • 导入所有资源 import collection.mutable._
    • 可在任意位置进行导入操作
    • selector
      • 选择性的导入一部分成员,import java.awt.{Color, Font}
      • 为导入成员取别名:import java.util.{HashMap => JavaMap}
      • 隐藏成员: import java.util.{HashMap => _, _} // 避免产生混淆
    • 隐式导入,默认导入三个 java.lang, scalaPredef
      • 后面导入的可将前面的成员覆盖,避免冲突
      • 导入 scala 相关的包可省略 scala 路径

Inheritance

fragile base class 基类被继承之后,修改基类可能会对子类造成无法预期的影响

  • 继承类,与 Java 一样使用 extends 关键字

    • final 类不能被继承, final 字段、方法不能被覆盖
  • 覆盖非抽象方法,必须使用 override 关键字
  • 抽象方法
    • 无方法体的方法,可以省略 abstract 关键字;子类覆盖时也可以省略 override
  • 抽象字段
    • 无初始值的字段,可省略 abstract 关键字,子类覆盖式也可省略 override
  • 调用父类方法,使用 super 关键字
  • 类型检查和转换, isInstanceOf, asInstanceOf;获取类型, classOf
    • 模式匹配通常是个更好的类型检查方式
  • protected 不同于 Java,受保护成员在包内不可见
  • 辅助构造器不可直接调用超类构造器
    • 可在定义类时直接在 extends 时调用超类构造器并传递参数
    • 继承 Java 类时主构造器必须调用超类的构造器
  • 覆盖字段
    • def 只能覆盖 def
    • val 只能覆盖 无参数的 def
    • var 只能覆盖 抽象的 var
  • 继承层级

    • Any 定义了 asInstanceOf, isInstanceOf,判断相等,hash值等方法
    • AnyRef 是除基础类型外所有类的父类,等价于 java.lang.Object
      • 提供方法 wait, notify/notifyAllsynchronized
    • AnyVal 不包含任何方法,只是个值类型的标记
    • 所有 Scala 类都实现了 ScalaObject 这个标记接口,该接口无任何方法
    • Null 的唯一实例 null,可分配给引用类型,但不可分配给值类型(Int 不可为 null)
    • Nothing 无实例,在泛型构造时有用,Nil 类型为 List[Nothing]
    • ??? 方法声明返回类型为 Nothing, 无返回值,会抛出 NotImplementedError,用于预留未实现的方法
    • Unit 代表空/void,类型唯一值为 ()
    • 如果方法参数类型为 AnyAnyRef, 当传递多个参数时,会被替换为 tuple
  • equalshashCode 判断对象相等
    • 可使用模式匹配实现 equals
    • equals 参数类型为 Any 而不是具体的类型
    • ##hashCode 的安全版本,遇到 null 会返回 0 而不是抛出异常
  • 值类 Value Class
    • 继承 AnyVal
    • 主构造器只有一个参数 val,无构造体
    • 无其他构造器和字段
    • 自动提供的 equalshashCode 比较实际值
    • 用于隐式转换
      • 其他用途,如 class a(x: Int, y: Int) 设计为 class a(x: X, y: Y) ,定义值类 X, Y 避免混淆参数

Scala Class etc.的更多相关文章

  1. jdb调试scala代码的简单介绍

    在linux调试C/C++的代码需要通过gdb,调试java代码呢?那就需要用到jdb工具了.关于jdb的用法在网上大家都可以找到相应的文章,但是对scala进行调试的就比较少了.其实调试的大致流程都 ...

  2. scala练习题1 基础知识

    1, 在scala REPL中输入3. 然后按下tab键,有哪些方法可以被调用? 24个方法可以被调用, 8个基本类型: 基本的操作符, 等:     2,在scala REPL中,计算3的平方根,然 ...

  3. 牛顿法求平方根 scala

    你任说1个整数x,我任猜它的平方根为y,如果不对或精度不够准确,那我令y = (y+x/y)/2.如此循环反复下去,y就会无限逼近x的平方根.scala代码牛顿智商太高了println( sqr(10 ...

  4. Scala集合和Java集合对应转换关系

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用Scala编码的时候,经常会遇到scala集合和Java集合互相转换的case,特意mark一 ...

  5. Scala化规则引擎

    1. 引言 什么是规则引擎 一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑.业务规则通常应该由业务分析人员和策略管理者开发和修改,但有些复杂的业务规则也可以由技 ...

  6. Scala快速概览

    IDEA工具安装及scala基本操作 目录 一. 1. 2. 3. 4. 二. 1. 2. 3. 三. 1. 2. 3. 4. 5. 6. 7. 四. 1. (1) (2) (3) (4) (5) ( ...

  7. Scala Macros - scalamela 1.x,inline-meta annotations

    在上期讨论中我们介绍了Scala Macros,它可以说是工具库编程人员不可或缺的编程手段,可以实现编译器在编译源代码时对源代码进行的修改.扩展和替换,如此可以对用户屏蔽工具库复杂的内部细节,使他们可 ...

  8. Scala Macros - 元编程 Metaprogramming with Def Macros

    Scala Macros对scala函数库编程人员来说是一项不可或缺的编程工具,可以通过它来解决一些用普通编程或者类层次编程(type level programming)都无法解决的问题,这是因为S ...

  9. Scala Reflection - Mirrors,ClassTag,TypeTag and WeakTypeTag

    反射reflection是程序对自身的检查.验证甚至代码修改功能.反射可以通过它的Reify功能来实时自动构建生成静态的Scala实例如:类(class).方法(method).表达式(express ...

  10. Scala For Java的一些参考

          变量 String yourPast = "Good Java Programmer"; val yourPast : String = "Good Java ...

随机推荐

  1. 王某人从0开始学习lorawan的笔记_0

    最近老板想做lorawan的项目,交给我了,我也应承下来了,但是!!!我TM连lorawan是啥子我都不知道啊啊啊啊啊! 真希望我女朋友可以看穿我的倔强,给我1千万,让我专心当舔狗,等等,我的女朋友? ...

  2. CentOS搭建php + nginx环境

    更新Centos的yum源 yum update 安装EPEL源和REMI源 yum install epel-release yum install http://rpms.remirepo.net ...

  3. effective java 3th 序

    正本基本是自己翻译,翻译绝对有错误,就是这么自信,看的时候,自己注意下,如果感觉有语句不通,那么可能就是我翻译的出现了问题,可以自己翻找原文对比下. 其中自己的见解,我写在脚注中. 在 1997 年, ...

  4. 良许 | 网络检测神器 ss 命令,你可能根本就不会用!

    今天我们来介绍一下 Linux ss 命令. ss 是 Socket Statistics 的缩写,用来统计 socket 连接的相关信息,它跟 netstat 差不多,但有着比 netstat 更强 ...

  5. [企业微信通知系列]Jenkins发布后自动通知

    一.前言 最近使用Jenkins进行自动化部署,但是部署后,并没有相应的通知,虽然有邮件发送通知,但是发现邮件会受限于接收方的接收设置,导致不能及时看到相关的发布内容.而由于公司使用的是企业微信,因此 ...

  6. Atcoder/Topcoder 口胡记录

    Atcoder/Topcoder 理论 AC Atcoder的❌游戏示范 兴致勃勃地打开一场 AGC 看 A 题,先 WA 一发,然后花了一年时间 Fix. 看 B 题,啥玩意?这能求? 睡觉觉. e ...

  7. 洛谷P1939【模板】矩阵加速(数列)+矩阵快速幂

    思路: 这个 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 可以想成: [a(n) ] [1 0 1] [a(n-1)   ] [a(n-1) ] =    ...

  8. J farm

    #include<iostream> #include<vector> #include<algorithm> #include<cstring> #i ...

  9. java hdu A+B for Input-Output Practice (III)

    A+B for Input-Output Practice (III) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32 ...

  10. 3. Sentinel源码分析— QPS流量控制是如何实现的?

    Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 上回我们用基于并 ...