Scala中对象和类之间的区别

时间:2009-11-18 11:21:58

标签: scala class object

我只是在互联网上阅读一些Scala教程,并注意到在一些例子中,在示例的开头声明了一个对象。

Scala中classobject之间的区别是什么?

14 个答案:

答案 0 :(得分:517)

TL;博士

  • class C定义一个类,就像在Java或C ++中一样。
  • object O创建一个singleton对象O作为某个匿名类的实例;它可用于保存与某些类的实例无关的静态成员。
  • object O extends T使对象O成为trait T的实例;然后,您可以将O传递到任何地方,预计会T
  • 如果有class C,则object CC类的companion object;请注意,随播广告对象会自动成为C
  • 的实例

另请参阅objectclass的Scala文档。

用作静态成员的主机

通常,您需要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本身用作类或特征的一些特殊实例。 执行此操作时,您的对象需要扩展一些trait才能成为其子类的实例。

请考虑以下代码:

object A extends B with C {
  ...
}

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

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

object

的其他功能

Scala中还存在一些对象的特殊功能。 我建议您阅读official documentation

  • def apply(...)启用A(...)
  • 的常用方法无名称语法
  • def unapply(...)允许创建自定义模式匹配extractors
  • 如果附带同名的类,则该对象在解析implicit parameters时扮演特殊角色

答案 1 :(得分:240)

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

答案 2 :(得分:66)

对象具有一个实例(您无法调用new MyObject)。您可以拥有多个类的实例。

Object提供相同(以及一些额外的)目的作为Java中的静态方法和字段。

答案 3 :(得分:17)

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

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

  • 它可以像一个模块,包含相关/辅助类型和定义等。

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

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

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

  • 它引入了单例类型。

它是一个非常强大和一般的结构。 Scala初学者可能非常困惑的是,相同的构造可以有非常不同的用途。 object可以同时为这些不同的用途提供服务,这可能会更加令人困惑。

答案 4 :(得分:15)

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

答案 5 :(得分:12)

正式的差异 -

  1. 您无法为对象
  2. 提供构造函数参数
  3. 对象不是类型 - 您可能无法使用new运算符创建实例。但它可以有字段,方法,扩展超类和混合特征。
  4. 使用上的差异:

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

      object Hello {
        def main(args: Array[String]) {
          println("Hello, World!")
        }
      }
      
    • 您也可以在java中使用单例对象时使用它。



答案 6 :(得分:4)

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

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

答案 7 :(得分:2)

对象是一个类,但它已经是(是)一个实例,因此您无法调用new ObjectName。另一方面, Class 只是类型,它可以是调用new ClassName()的实例。

答案 8 :(得分:2)

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

Scala Singleton对象示例

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中,当你有一个与singleton对象同名的类时,它被称为伴随类,而singleton对象被称为伴随对象。

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

Scala Companion对象示例

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);  
    }  
} 

对不起,我来不及但我希望它会对你有帮助。

答案 9 :(得分:1)

Scala类与Java类相同,但scala不会在类中为您提供任何入口方法,例如java中的main方法。与object关键字相关的主要方法。您可以将object关键字视为创建隐式定义的类的单例对象。

更多信息请查看此文章 class and object keyword in scala programming

答案 10 :(得分:0)

对象等于Java中的静态类,有些扩展,静态类意味着静态类在放入JVM时需要创建对象,它可以被它的类名使用直接

答案 11 :(得分:0)

如果您来自Java背景,则scala中的类概念类似于Java,但是scala中的类不能包含静态成员。

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

答案 12 :(得分:0)

一个类与其他语言的任何其他类一样。您可以像定义任何其他语言一样定义类,就像其他任何语言一样。

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

但是,对象是仅具有单个对象的类。这很有趣,因为它可以用于使用 companion对象创建类的静态成员。该伴随对象可以访问类定义的私有成员,并且与您要定义的类具有相同的名称。

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中使用单例对象那样在对象内部创建它们以避免重复。

答案 13 :(得分:-24)

Class&amp; object:类是描述实体或对象的所有属性的定义。而object是一个类的实例。