scala中对象和类的区别

Difference between object and class in Scala

我将在互联网上浏览一些scala教程,并注意到在一些示例中,在示例的开头声明了一个对象。

scala中的classobject有什么区别?


DR

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

另请参见scala文档了解对象和类。

用作静态成员的宿主

通常,您需要一个object来保存方法和值/变量,这些方法和值/变量不需要先实例化某个类的实例就可以使用。这与Java中EDCOX1、14个成员的使用密切相关。

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

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

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

1
2
3
4
5
6
class A() {
  def twice(i: Int): Int = 2 * i
}

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

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

用作特殊命名实例

您也可以将object本身用作类或特性的一些特殊实例。当您这样做时,您的对象需要扩展一些trait,以便成为它的子类的一个实例。

请考虑以下代码:

1
2
3
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可见性。但是,这些方法不会自动导入。您要么显式地导入它们,要么在它们前面加上类/对象名称。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
   }
}


一个对象只有一个实例(不能调用new MyObject)。一个类可以有多个实例。

对象与Java中的静态方法和字段具有相同的(和一些附加的)目的。


正如许多人所解释的,object定义了一个单例实例。我认为这里的答案中有一点被遗漏了,那就是object有多种用途。

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

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

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

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

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

  • 它引入了单例类型。

这是一个非常强大和一般的结构。对于scala初学者来说,非常令人困惑的是,相同的结构可以有非常不同的用途。而一个object可以同时提供许多不同的用途,这可能会更加令人困惑。


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


形式上的区别-

  • 不能为对象提供构造函数参数
  • 对象不是类型-不能使用新运算符创建实例。但它可以有领域、方法、扩展超类和混合特性。
  • 使用上的差异:

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

      1
      2
      3
      4
      5
      object Hello {
        def main(args: Array[String]) {
          println("Hello, World!")
        }
      }
    • 在Java中使用单元格对象时,也可以使用它。

      nbsp;nbsp;&(b)nbsp;nbsp;


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

    斯卡拉没有等价于Java的静态关键字,并且在斯卡拉中经常使用一个对象,您可以在Java中使用具有静态成员的类。


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

    scala singleton对象示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    object Singleton{  
        def main(args:Array[String]){  
            SingletonObject.hello()         // No need to create object.  
        }  
    }  


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

    输出:

    1
    Hello, This is Singleton Object

    在scala中,当有一个类与singleton对象同名时,它被称为伴生类,singleton对象被称为伴生对象。

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

    scala伴生对象示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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.")  
        }  
    }

    输出:

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

    在scala中,类可以包含:

    1。数据成员

    2。成员法

    三。构造函数块

    4。嵌套类

    5。高级信息等。

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

    scala类示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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);  
        }  
    }

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


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


    Scala类与Java类相同,但Scala不提供类中的任何输入方法,如Java中的main方法。与对象关键字关联的主方法。可以将object关键字视为创建隐式定义的类的singleton对象。

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


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

    Scala中的对象是单体类型,在对象中使用对象名称调用方法,在Scala对象中是关键字,而Java对象是类的实例。


    对象等于Java中的静态类到一些扩展,静态特性意味着静态类在向JVM放置时不需要创建对象,它可以直接由它的类名使用。


    类对象:类是描述实体或对象的所有属性的定义。对象是类的一个实例。