Scala 中 object、class 与 trait 的区别
Scala 中 object、class 与 trait 的区别
引言
当你刚入门 Scala,肯定会迫不及待想要编写自己的第一个 Scala 程序。如果你已经在交互模式下敲过 Scala 代码,想必你更乐意尝试在 IDEA 下写 Scala 代码。当你打开 IDEA,满心期待的创建自己的第一个 Scala 工程,接着创建一个 Scala 类,如下:

你会发现这里有好几种类型,如果你之前学过 Java,你会毫不犹豫选择第一个 Class 类型,然后快速写下如下代码:
class MyFirstScala {
def main(args: Array[String]): Unit = {
prinln("hello scala")
}
}
当你正打算运行这个 main 方法时,却发现无法执行,我猜你肯定当时就郁闷了。
要让 main 方法执行其实很简单,只需要将 class 改为 object 即可,如下:
object MyFirstScala {
def main(args: Array[String]): Unit = {
prinln("hello scala")
}
}
这到底是怎么回事呀?
object
单例对象概念
我们都知道 Scala 与 Java 一样,是一种面向对象的编程语言;但是 Scala 却与 Java 有所不同,就是 Scala 具有直接创建对象的能力,该对象无需类即可定义其成员。
什么意思呀?就是不需要定义 class 类,也不需要 new,就能直接创建一个对象。而且创建对象的方式和定义类的方式是一样的,唯一的区别就是创建对象要使用 object 关键字。
通过 object 直接创建的对象,我们称为单例对象。 为何叫单例对象,因为单例对象是没有类就可以存在的对象,这样的对象是独一无二的,不像通过 class 方式可以 new 无数的对象。
那为何 Scala 中程序入口 main() 方法一定要放在 object 创建的单例对象中执行,而不能像 Java 一样?
许多面向对象的编程语言包括 Java 都是使用 static 关键字修饰 main() 方法,这样 main() 方法就变成了类静态方法,这样在类加载完成后就可以直接调用 main() 方法了。
但是,Scala 根本就没有 static 关键字, 也没有类静态方法和静态属性。这就是为什么在 Scala 中 main() 方法只能放在 object 定义的单例对象中执行。
单例对象定义
object singleton_objname {
// object code , member functions and fields.
}
注意:object 不能提供构造器参数,也就是说 object 必须是无参的
单例对象用法
object findsum{
var a = 56
var b = 21
def sum(): Int ={
return a+b;
}
}
object Main
{
def print(){
printf("The sum is : "+ findsum.sum());
}
def main(args: Array[String])
{
print();
}
}
伴生对象和伴生类
如果类和单例对象具有相同的名称,那么该类为该对象的同伴类,而该对象为该类的伴生对象 。
伴生对象与伴生类在 Scala 的面向对象编程方法中占据极其重要的位置,主要用于代替 Java 静态成员变量与静态方法,很多 Scala 工具方法都是采用单例对象或伴生对象实现的。
伴生类与伴生对象可以互相访问彼此的私有属性或方法,但是必须都在同一源文件
class companion{
var a = 23;
var b = 78;
def sum(){
println("The sum is: "+ (a+b));
}
}
object companion{
def main(args:Array[String]){
new companion().sum();
}
}
class
Scala 是一种面向对象的编程语言,所以其定义和使用类的方式和 Java 基本相同,不过 Scala 也有一些不同的地方之处
构造器
主构造器
Scala 中每个类都有且只有一个主构造器,且主构造器会执行类定义中的所有语句
class Student(val name: String,val age: Int){ // 括号中的就是主构造器的参数
println("Primary constructor") // 该语句属于主构造器的一部分
...
}
只有主构造器的参数才会被编译成字段,其初始化的值为构造时传入的参数。
可以在主构造器中使用默认参数,可防止辅助构造器使用过多。
class Student(val name: String = "",val age: Int = 0){ // 主构造器的默认参数
...
}
辅助构造器
辅助构造器的名称为 this
class Student {
private var name = " "
private var age = 0 def this(name: String){ //辅助构造器1
this() //调用主构造器
this.name = name
} def this(name: String,age: Int){ //辅助构造器2
this(name) //调用前一个辅助构造器
this.age = age
}
}
每个辅助构造器都必须以一个对先前已定义的其他辅助构造器或主构造器的调用开始
私有构造器
想要让主构造器变成私有构造器,只需要加上 private 关键字即可
class Dog private(val age: Int) {
...
}
这样做之后,就必须使用辅助构造器来构造 Dog 对象了
属性(成员变量)
scala 对每个类属性或成员变量都会提供 getter 和 setter 方法,同时也可以显示的声明,但是针对 val 类型,只提供getter 方法,默认情况下,字段为 public 类型
trait
在 Scala 中 trait(特征) 相当于 Java 的接口,与接口不同的是它还可以定义属性和方法的实现,这一点又更像 Java 的抽象类。
一般情况下 Scala 的类只能够继承单一父类,但是如果是 trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
trait Person {
def getInfo(): String
}
class Man(var name: String, var age: Int) extends Person {
override def getInfo(): String = {
s"info:name=${name},age=${age}"
}
}
总结
在 Scala 中,object 用于定义单例对象,class 用于定义类,trait 用于定义接口。至于还有两个 case class / case object 类型,主要用于支持模式匹配。
Scala 中 object、class 与 trait 的区别的更多相关文章
- html中object和embed标签的区别
♦object定义一个嵌入的对象.请使用此元素向您的 XHTML 页面添加多媒体.此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码. ♦<object&g ...
- Scala中 object 和 class的区别
object 在scala中没有静态方法和静态字段,所以在scala中可以用object来实现这些功能,直接用对象名调用的方法都是采用这种实现方式,例如Array.toString.对象的构造器在第一 ...
- Scala 中object和class的区别
Scala中没有静态类型,但是有有“伴侣对象”,起到类似的作用. Scala中类对象中不可有静态变量和静态方法,但是提供了“伴侣对象”的功能:在和类的同一个文件中定义同名的Object对象:(须在同一 ...
- Scala 中的函数式编程基础(三)
主要来自 Scala 语言发明人 Martin Odersky 教授的 Coursera 课程 <Functional Programming Principles in Scala>. ...
- Spark基础-scala学习(三、Trait)
面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...
- (数据科学学习手札46)Scala中的面向对象
一.简介 在Scala看来,一切皆是对象,对象是Scala的核心,Scala面向对象涉及到class.object.构造器等,本文就将对class中的重点内容进行介绍: 二.Scala中的类 2.1 ...
- scala class和object,trait的区别
Scala类 1 2 3 4 5 6 7 8 9 10 11 12 13 class Counter { private var value = 0 // 必须初始化字段 def increm ...
- scala 学习笔记(05) OOP(中)灵活的trait
trait -- 不仅仅只是接口! 接上回继续,scala是一个非常有想法的语言,从接口的设计上就可以发现它的与众不同.scala中与java的接口最接近的概念是trait,见下面的代码: packa ...
- 第2节 Scala中面向对象编程:12、13、14、15、16、trait
6.4. Scala中面向对象编程之trait 6.4.1. 将trait作为接口使用 Scala中的trait是一种特殊的概念: 首先先将trait作为接口使用,此时的trait就与Java ...
随机推荐
- 201871030112-贾傲羊 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告
项目 内容 课程班级博客链接 课程班级博客链接 这个作业要求链接 作业要求链接 我的课程学习目标 学习PSP流程并运用于结对项目:学习GitHub代码的管理;学习结对编程的流程与内容 这个作业在哪些方 ...
- Dynamics CRM使用JS隐藏自定义按钮
在我们平时客制化开发的时候会经常遇到要制作自定义按钮的情况,而这个自定义按钮的功能又经常会有一些隐藏逻辑需要实现,所以每次通过获取控件查找这个按钮再隐藏比较麻烦,而且偶尔会出现代码没起作用的效果.下面 ...
- ubuntu apt出错
whitedream@ubuntu:~$ sudo apt-get update Reading package lists... Done E: Could not get lock /var/li ...
- Java 高精度浮点数计算工具
说起编程中的高精度数值,我第一反应就是double类型了.的确,double阶码11位,尾数52位,几乎能应对任何苛刻的要求......然而,当我天真地尝试用double来算泰勒展开式的函数值,离散代 ...
- LinqToObject和LinqToSql的区别
抓住五一假期尾巴和小伙伴们一起分享这两者的区别.大家在日常编码的过程当中肯定也注意过或者使用过.但是二者其实存在本质的区别 1.什么是LinqToObject呢? LINQ to Objects指直接 ...
- 软件篇-01-为Jetson TX2扫清科研的障碍
建议用vryL,GUI界面,功能更全,支持订阅. https://github.com/ShieldQiQi/vryLgithub.com 下面的内容不用看了,除非你更喜欢命令行界面. To r ...
- 从苏宁电器到卡巴斯基第28篇:难忘的三年硕士时光 VI
想要毕业,还需满足一个要求 像我们这种三年制的工科硕士,想要毕业的话,除了需要按照要求完成毕业论文以外,还需要在相关期刊上发表一篇与毕业论文相关的小论文,或者申请软件著作权,或者申请专利.我不知道别的 ...
- Linux中的SSH服务
目录 SSH 使用scp在两台Linux间传数据: 基于SSH做远程访问,可以使用ftp服务的相关指令sftp root@192.168.10.10 Openssh公私钥验证: SSH SSH(Sec ...
- 逆向 ctype.h 函数库 isalnum、iscntrl、islower、isxdigit、tolower 函数
0x01 isalnum 函数 函数原型:int isalnum(int c); 函数功能:检查所传的字符是否是字母和数字 动态链接库:ucrtbase.dll C\C++ 实现: #define _ ...
- 使用QT creator实现一个五子棋AI包括GUI实现(8K字超详细)
五子棋AI实现 五子棋游戏介绍 五子棋的定义 五子棋是全国智力运动会竞技项目之一,是具有完整信息的.确定性的.轮流行动的.两个游戏者的零和游戏.因此,五子棋是一个博弈问题. 五子棋的玩法 五子棋有两种 ...