Scala 中 object、class 与 trait 的区别

时间:2023-02-24 17:06:12

Scala 中 object、class 与 trait 的区别

引言

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

Scala 中 object、class 与 trait 的区别

你会发现这里有好几种类型,如果你之前学过 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 的区别的更多相关文章

  1. html中object和embed标签的区别

    ♦object定义一个嵌入的对象.请使用此元素向您的 XHTML 页面添加多媒体.此元素允许您规定插入 HTML 文档中的对象的数据和参数,以及可用来显示和操作数据的代码. ♦<object&g ...

  2. Scala中 object 和 class的区别

    object 在scala中没有静态方法和静态字段,所以在scala中可以用object来实现这些功能,直接用对象名调用的方法都是采用这种实现方式,例如Array.toString.对象的构造器在第一 ...

  3. Scala 中object和class的区别

    Scala中没有静态类型,但是有有“伴侣对象”,起到类似的作用. Scala中类对象中不可有静态变量和静态方法,但是提供了“伴侣对象”的功能:在和类的同一个文件中定义同名的Object对象:(须在同一 ...

  4. Scala 中的函数式编程基础&lpar;三&rpar;

    主要来自 Scala 语言发明人 Martin Odersky 教授的 Coursera 课程 <Functional Programming Principles in Scala>. ...

  5. Spark基础-scala学习(三、Trait)

    面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...

  6. (数据科学学习手札46)Scala中的面向对象

    一.简介 在Scala看来,一切皆是对象,对象是Scala的核心,Scala面向对象涉及到class.object.构造器等,本文就将对class中的重点内容进行介绍: 二.Scala中的类 2.1 ...

  7. 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 ...

  8. scala 学习笔记&lpar;05&rpar; OOP(中)灵活的trait

    trait -- 不仅仅只是接口! 接上回继续,scala是一个非常有想法的语言,从接口的设计上就可以发现它的与众不同.scala中与java的接口最接近的概念是trait,见下面的代码: packa ...

  9. 第2节 Scala中面向对象编程:12、13、14、15、16、trait

    6.4.  Scala中面向对象编程之trait 6.4.1.    将trait作为接口使用 Scala中的trait是一种特殊的概念: 首先先将trait作为接口使用,此时的trait就与Java ...

随机推荐

  1. Visual Studio 2010 下 安装RGiesecke&period;DllExport

    RGiesecke.DllExport 在 UnmanagedExports 中.安装过程如下: 1.首先在"工具"菜单下的"扩展管理器"中,安装 NuGet ...

  2. Copy-On-Write容器

    Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改, ...

  3. Quartz&period;net misfire实践

      1.问题描述 在使用Quartz.net定时运行作业时,存在一种情况:作业错过了某次执行,当作业恢复的时候应该怎么处理?如:job1在3:50的时候应该执行的,但此刻job1处于暂停状态,而到3: ...

  4. sqlite3经常使用命令&amp&semi;amp&semi;语法

    http://blog.csdn.net/linchunhua/article/details/7184439 sqlite数据库仅仅用一个文件就ok,小巧方便,所以是一个很不错的嵌入式数据库,SQL ...

  5. 遇到安装app不识别的情况

    一般->blokfile->证书设定设置

  6. ASP&period;NET Core学习之五 EntityFrameworkCore

    目的:运用EntityFrameworkCore ,使用codefirst开发 一.创建web项目 创建一个不进行身份验证的   ASP.NET Core Web Application (.NET ...

  7. Flutter环境搭建

    本文介绍mac上搭建Flutter环境 1.Flutter官方提供中国地区镜像地址:https://github.com/flutter/flutter/wiki/Using-Flutter-in-C ...

  8. JavaScript自定义鼠标右键菜单

    下面为JavaScript代码 window.onload = function () { //好友列表 var f = 0; //判断指定id的元素在页面中是否存在 if (document.get ...

  9. js&comma;ajax&comma;layer笔记&lpar;弹出层&comma;在弹出一个弹框&rpar;

    整体认识: 因为作用域的问题,js 在页面初次加载时已近加载好了,所以要有第二次弹窗的效果,必须得在第一次成功之后再次让他加载js 代码: /*shaun*/showdetailsPag: funct ...

  10. Oracle数据安全(四)j角色管理

    一.角色管理的概述 1.角色的概念 为了简化数据库权限的管理,在Oracle数据库中引入了角色的概念.所谓的角色就是一系列相关权限的集合. 2.角色的特点 在数据库中,角色的名称必须是唯一的,不能与用 ...