Scala中对象和类之间的区别

Ste*_*eve 600 scala class object

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

classobjectScala有什么区别?

zig*_*tar 547

TL;博士

  • class C 定义一个类,就像在Java或C++中一样.
  • object O创建一个单例对象O作为某个匿名类的实例; 它可用于保存与某些类的实例无关的静态成员.
  • object O extends T使对象O成为trait T; 然后你可以通过O任何地方,一个T是预期的.
  • 如果有class C,那么object C是阶级的伴侣C ; 请注意,伴随对象不是自动的实例C.

另请参阅对象类的 Scala文档.

用作静态成员的主机

大多数情况下,您需要一个object可以保存的方法和值/变量,而无需首先实例化某个类的实例.这与staticJava中的成员密切相关.

object A {
  def twice(i: Int): Int = 2*i
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用上面的方法调用A.twice(2).

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

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

val a = new A()
a.twice(2)
Run Code Online (Sandbox Code Playgroud)

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

用作特殊命名实例

您还可以将object自身用作类或特征的一些特殊实例.当你这样做时,你的对象需要扩展一些trait,以便成为它的子类的实例.

请考虑以下代码:

object A extends B with C {
  ...
}
Run Code Online (Sandbox Code Playgroud)

该声明首先声明,同时扩展匿名(无法访问)类BC,并演示了这种名为类的一个实例A.

这个装置A可以被传递到期望类型的对象的功能BC,或B with C.

附加功能 object

Scala中还存在一些对象的特殊功能.我建议阅读官方文档.

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

  • 它还将定义类A,并将对象A中的所有方法创建为类A上的静态方法(用于与Java交互).(Modulo Scala 2.7中已在Scala 2.8中修复的错误) (37认同)
  • @Hendy:Scala不会识别`Commerce`类,但JVM和Java语言会识别.(这就是你如何做`对象Foo {def main(args:Seq [String])}`并期望程序运行.) (3认同)
  • 我认为ziggystar的答案更精确,该类是一个匿名类,除非明确定义了名为Commerce的相应类(然后Commerce对象将成为Commerce类的伴随对象) (3认同)
  • @DavidApltauer我打赌有足够的微妙之处,我的答案没有涵盖.但对于大多数读这篇文章的人来说,那些可能并不重要 并且我从来没有将对象作为某个特征的实例传递出来的问题,这并不意味着它们不存在; 但它应该工作. (3认同)
  • @KenBloom真的吗?我尝试过但不起作用:scala> Commerce res8:Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>:23:错误:找不到:类型Commerce classOf [Commerce] ^ scala> new Commerce <控制台>:23:错误:未找到:键入Commerce新商务^ (2认同)

Dan*_*ral 243

A class是定义,描述.它根据方法和其他类型的组成定义了一种类型.

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

object和之间有关系class.如果一个对象具有相同的名称,则该对象被称为类的伴随对象.发生这种情况时,每个人都可以访问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
   }
}
Run Code Online (Sandbox Code Playgroud)

  • @ithkuil完成.抱歉这个愚蠢的例子,我想不出一个好的和短的. (4认同)

Tho*_*ung 70

一个对象只有一个实例(你不能调用new MyObject).您可以拥有一个类的多个实例.

Object提供 Java中的静态方法和字段相同(以及一些其他)目的.


acj*_*jay 18

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

  • 它可以是伴侣对象为class/ trait,包含了可能被认为是静态的方法或便捷方法.

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

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

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

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

  • 它引入了单例类型.

这是一个非常强大和一般的结构.Scala初学者可能会感到非常困惑的是,相同的构造可能会有很多不同的用途.并且object可以同时服务于许多这些不同的用途,这可能更令人困惑.


Ken*_*oom 17

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


iru*_*yak 15

正式的区别 -

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

使用差异:

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

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 您也可以在java中使用singleton对象时使用它.

      
        
      


Yon*_*Noh 6

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


Bha*_*Das 6

在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")  
    }  
}  
Run Code Online (Sandbox Code Playgroud)

输出:

Hello, This is Singleton Object
Run Code Online (Sandbox Code Playgroud)

在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.")  
    }  
}  
Run Code Online (Sandbox Code Playgroud)

输出:

Hello, this is Companion Class.
And this is Companion Object.
Run Code Online (Sandbox Code Playgroud)

在 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);  
    }  
} 
Run Code Online (Sandbox Code Playgroud)

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


小智 5

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

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