Scala中对象和类的区别

我正在浏览Internet上的一些Scala教程,并注意到在一些示例中,在示例的开头声明了一个对象。

Scala中的classobject有什么区别?

231370 次浏览

一个对象正好有一个实例(您不能调用new MyObject)。您可以拥有一个类的多个实例。

对象将相同(和一些附加的)目的用作Java中的静态方法和字段。

tl; dr

  • class C定义了一个类,就像Java或C++。
  • object O创建一个单例对象O作为某个匿名类的实例;它可用于保存与某个类的实例不关联的静态成员。
  • object O extends T使对象O成为trait T的实例;然后您可以在任何地方传递O,预计会有T
  • 如果有一个class C,那么object C就是类C伴生物体;注意伴随对象是没有自动成为C的实例。

另请参阅Scala留档对象

object作为静态成员的主机

大多数情况下,您需要object来保存方法和值/变量,而无需首先实例化某个类的实例。 这种用法与Java中的static成员密切相关。

object A {
def twice(i: Int): Int = 2*i
}

然后,您可以使用A.twice(2)调用上述方法。

如果twice是某个类A的成员,那么您需要先创建一个实例:

class A() {
def twice(i: Int): Int = 2 * i
}


val a = new A()
a.twice(2)

您可以看到这是多么冗余,因为twice不需要任何特定于实例的数据。

object作为特殊命名实例

您还可以使用object本身作为类或trait的一些特殊实例。 当您这样做时,您的对象需要扩展一些trait才能成为它的子类的实例。

考虑以下代码:

object A extends B with C {
...
}

此声明首先声明一个扩展BC的匿名(不可访问)类,并实例化名为A的此类的单个实例。

这意味着A可以传递给期望对象类型为BCB with C的函数。

object的附加功能

Scala中也存在一些对象的特殊特性。 我推荐阅读官方留档

  • def apply(...)启用A(...)的常用方法无名称语法
  • def unapply(...)允许创建自定义模式匹配提取器
  • 如果伴随同名类,则对象在解析隐式参数时承担特殊角色

class是一个定义,一个描述。它根据方法和其他类型的组合来定义一个类型。

object是单例——保证是唯一的类的实例。对于代码中的每个object,都会创建一个匿名类,它继承自你声明object要实现的任何类。这个类不能从Scala源代码中看到——尽管你可以通过反射获得它。

objectclass之间有关系。如果一个对象共享相同的名称,则称其为一个类的伴随对象。发生这种情况时,每个对象都可以访问另一个中private可见性的方法。不过,这些方法不会自动导入。你要么必须显式导入它们,要么用类/对象名称作为前缀。

例如:

class X {
// class X can see private members of object X
// Prefix to call
def m(x: Int) = X.f(x)


// Import and use
import X._
def n(x: Int) = f(x)


private def o = 2
}


object X {
private def f(x: Int) = x * x


// object X can see private members of class X
def g(x: X) = {
import x._
x.o * o // fully specified and imported
}
}

在Scala中定义一个对象就像在Java中定义一个只有静态方法的类。然而,在Scala中,一个对象可以扩展另一个超类,实现接口,并像一个类的实例一样传递(所以这就像一个类的静态方法,但更好)。

形式上的区别——

  1. 您不能为对象提供构造函数参数
  2. 对象不是一个类型-你不能使用new运算符创建实例。但它可以有字段、方法、扩展超类和混合特征。

用法上的区别:

  • Scala没有静态方法或字段。相反,您应该使用object。您可以与或不与相关类一起使用它。在第一种情况下,它被称为同伴对象。你必须:
    1. 对类和对象使用相同的名称
    2. 将它们放在同一个源文件中。
  • 要创建程序,您应该使用object中的main方法,而不是class中的main方法。

    object Hello {
    def main(args: Array[String]) {
    println("Hello, World!")
    }
    }
    
  • You also may use it as you use singleton object in java.

      
        
      

正如许多人所解释的那样,object定义了一个单例实例。我认为这里的答案中遗漏的一件事是object有几个目的。

  • 它可以是class/trait的同伴对象,包含可能被认为是静态方法或便利方法的内容。

  • 它可以像一个模块一样工作,包含相关/附属类型和定义等。

  • 它可以通过扩展class或一个或多个trait来实现接口。

  • 它可以表示不包含数据的sealed trait的情况。在这方面,它通常被认为比没有参数的case class更正确。只有case object实现器的sealed trait的特殊情况或多或少是枚举的Scala版本。

  • 它可以作为implicit驱动逻辑的证据。

  • 它引入了单例类型。

这是一个非常强大和通用的构造。让Scala初学者非常困惑的是,同一个构造可以有截然不同的用途。而object可以同时服务于许多这些不同的用途,这可能会更令人困惑。

该对象在Java上类似于静态类,静态特性意味着静态类在放入JVM时不需要创建一个对象,它可以直接由它的类名使用,并且无论在哪里使用它都共享相同的实例(相同的数据状态)。

对象关键字创建了一个新的单例类型,就像只有一个命名实例的。如果您熟悉Java,在Scala中声明对象很像创建匿名类的新实例。

Scala没有等同于Java的静态关键字,并且在Scala中经常使用对象,您可以在Java中使用具有静态成员的类。

对象是一个类,但它已经有(是)一个实例,所以你不能调用new ObjectName。另一方面,只是类型,它可以通过调用new ClassName()成为一个实例。

Scala类与Java类相同,但scala不会在类中为您提供任何条目方法,就像java中的main方法一样。与对象关键字关联的main方法。您可以将对象关键字视为创建隐式定义的类的单例对象。

更多信息查看本文 scala编程中的类和对象关键字

在scala中,没有static概念。因此scala创建了一个单例对象来为您的程序执行提供切入点。 如果您不创建单例对象,您的代码将成功编译,但不会产生任何输出。在单例对象中声明的方法可以全局访问。单例对象可以扩展类和特征。

Scala单例对象示例

object Singleton{
def main(args:Array[String]){
SingletonObject.hello()         // No need to create object.
}
}




object SingletonObject{
def hello(){
println("Hello, This is Singleton Object")
}
}

输出:

Hello, This is Singleton Object

在scala中,当您有一个与单例对象同名的类时,它被称为同伴类,单例对象被称为同伴对象。

同伴类及其同伴对象都必须在同一个源文件中定义。

Scala伴侣对象示例

class ComapanionClass{
def hello(){
println("Hello, this is Companion Class.")
}
}
object CompanoinObject{
def main(args:Array[String]){
new ComapanionClass().hello()
println("And this is Companion Object.")
}
}

输出:

Hello, this is Companion Class.
And this is Companion Object.

在scala中,一个类可以包含:

1.数据成员

2.成员方法

3.构造器块

4.嵌套类

5.超级班级信息等。

您必须初始化类中的所有实例变量。没有默认范围。如果您不指定访问范围,它是公共的。必须有一个定义main方法的对象。它为您的程序提供起点。在这里,我们创建了一个类的示例。

类的Scala示例

class Student{
var id:Int = 0;                         // All fields must be initialized
var name:String = null;
}
object MainObject{
def main(args:Array[String]){
var s = new Student()               // Creating an object
println(s.id+" "+s.name);
}
}

对不起,我来晚了,但我希望它能帮助你。

如果你来自java背景,scala中类的概念有点类似于Java,但scala中的类不能包含静态成员。

scala中的对象是单例类型,您可以使用对象名称调用其中的方法,在scala中对象是关键字,在java中对象是类的实例

类就像其他语言中的任何其他类一样。您定义类就像任何其他语言一样,具有一些语法差异。

class Person(val name: String)
val me = new Person("My name")

然而,对象是一个只有单个对象的类。这使得它很有趣,因为它可以用来使用伴生物体创建类的静态成员。这个伴随对象可以访问类定义的私有成员,它与你正在定义的类同名。

class Person(var name: String) {


import Person._


def hi(): String = sayHello(name)
}


object Person {
private def sayHello(name: String): String = "Hello " + name
}


val me = new Person("My name")
me.hi()

另外,值得注意的是,对象类是懒惰创建的,这是另一个重要的点。因此,除非我们的代码中需要它们,否则不会实例化它们。

如果您正在为JDBC定义连接创建,您可以在对象中创建它们以避免重复,就像我们在Java单例对象时所做的那样。