简体   繁体   English

Scala中对象和类之间的区别

[英]Difference between object and class in Scala

I'm just going over some Scala tutorials on the Internet and have noticed in some examples an object is declared at the start of the example.我刚刚浏览了 Internet 上的一些 Scala 教程,并注意到在一些示例中,在示例的开头声明了一个对象。

What is the difference between class and object in Scala? Scala 中的classobject什么区别?

tl;dr tl;博士

  • class C defines a class, just as in Java or C++. class C定义了一个类,就像在 Java 或 C++ 中一样。
  • object O creates a singleton object O as instance of some anonymous class; object O创建一个单例对象O作为某个匿名类的实例; it can be used to hold static members that are not associated with instances of some class.它可用于保存与某个类的实例无关的静态成员。
  • object O extends T makes the object O an instance of trait T ; object O extends T使对象O成为trait T的实例; you can then pass O anywhere, a T is expected.然后你可以在任何地方传递O ,一个T是预期的。
  • if there is a class C , then object C is the companion object of class C ;如果存在class C ,则object C是类C伴生对象 note that the companion object is not automatically an instance of C .请注意,伴随对象不会自动成为C的实例。

Also see Scala documentation for object and class .另请参阅objectclass 的Scala 文档。

object as host of static members object作为静态成员的宿主

Most often, you need an object to hold methods and values/variables that shall be available without having to first instantiate an instance of some class.大多数情况下,您需要一个object来保存方法和值/变量,这些方法和值/变量无需先实例化某个类的实例即可使用。 This use is closely related to static members in Java.这种用法与 Java 中的static成员密切相关。

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

You can then call above method using A.twice(2) .然后您可以使用A.twice(2)调用上述方法。

If twice were a member of some class A , then you would need to make an instance first:如果twice是某个类A的成员,那么您需要先创建一个实例:

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

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

You can see how redundant this is, as twice does not require any instance-specific data.您可以看到这是多么冗余,因为twice不需要任何特定于实例的数据。

object as a special named instance object作为一个特殊的命名实例

You can also use the object itself as some special instance of a class or trait.您还可以将object本身用作类或特征的一些特殊实例。 When you do this, your object needs to extend some trait in order to become an instance of a subclass of it.当你这样做时,你的对象需要扩展一些trait才能成为它的子类的一个实例。

Consider the following code:考虑以下代码:

object A extends B with C {
  ...
}

This declaration first declares an anonymous (inaccessible) class that extends both B and C , and instantiates a single instance of this class named A .此声明首先声明一个匿名(不可访问)类,该类扩展BC ,并实例化名为A的此类的单个实例。

This means A can be passed to functions expecting objects of type B or C , or B with C .这意味着A可以传递给需要BC类型对象的函数,或者B with C

Additional Features of object object附加功能

There also exist some special features of objects in Scala. Scala 中还存在对象的一些特殊功能。 I recommend to read the official documentation .我建议阅读官方文档

  • def apply(...) enables the usual method name-less syntax of A(...) def apply(...)启用A(...)的常用方法无名称语法
  • def unapply(...) allows to create custom pattern matching extractors def unapply(...)允许创建自定义模式匹配提取器
  • if accompanying a class of the same name, the object assumes a special role when resolving implicit parameters如果伴随着一个同名的类,则该对象在解析隐式参数时承担特殊的角色

A class is a definition, a description.一个class是一个定义,一个描述。 It defines a type in terms of methods and composition of other types.它根据方法和其他类型的组合来定义类型。

An object is a singleton -- an instance of a class which is guaranteed to be unique.一个object是一个单例——一个保证唯一的类的实例。 For every object in the code, an anonymous class is created, which inherits from whatever classes you declared object to implement.对于代码中的每个object ,都会创建一个匿名类,该类继承自您声明object要实现的任何类。 This class cannot be seen from Scala source code -- though you can get at it through reflection.从 Scala 源代码中看不到这个类——尽管您可以通过反射来获得它。

There is a relationship between object and class . objectclass之间存在关系。 An object is said to be the companion-object of a class if they share the same name.如果对象具有相同的名称,则称它们为类的伴生对象。 When this happens, each has access to methods of private visibility in the other.发生这种情况时,每个人都可以访问另一个人的private可见性方法。 These methods are not automatically imported, though.但是,这些方法不会自动导入。 You either have to import them explicitly, or prefix them with the class/object name.您要么必须显式导入它们,要么使用类/对象名称作为前缀。

For example:例如:

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

An object has exactly one instance (you can not call new MyObject ).一个对象只有一个实例(你不能调用new MyObject )。 You can have multiple instances of a class.一个类可以有多个实例。

Object serves the same (and some additional) purposes as the static methods and fields in Java.对象与 Java 中的静态方法和字段具有相同(和一些额外)的用途

Defining an object in Scala is like defining a class in Java that has only static methods.在 Scala 中定义一个对象就像在 Java 中定义一个只有静态方法的类。 However, in Scala an object can extend another superclass, implement interfaces, and be passed around as though it were an instance of a class.然而,在 Scala 中,一个对象可以扩展另一个超类,实现接口,并像类的实例一样传递。 (So it's like the static methods on a class but better). (所以它就像类上的静态方法,但更好)。

As has been explained by many, object defines a singleton instance.正如许多人所解释的, object定义了一个单例实例。 The one thing in the answers here that I believe is left out is that object serves several purposes.我认为这里的答案中遗漏的一件事是object多种用途。

  • It can be the companion object to a class / trait , containing what might be considered static methods or convenience methods.它可以是class / trait的伴随对象,包含可能被视为静态方法或便利方法的内容。

  • It can act much like a module, containing related/subsidiary types and definitions, etc.它可以像一个模块一样运行,包含相关/子类型和定义等。

  • It can implement an interface by extending a class or one or more trait s.它可以通过扩展一个class或一个或多个trait来实现一个接口。

  • It can represent a case of a sealed trait that contains no data.它可以表示不包含数据的sealed trait的情况。 In this respect, it's often considered more correct than a case class with no parameters.在这方面,它通常被认为比没有参数的case class更正确。 The special case of a sealed trait with only case object implementors is more or less the Scala version of an enum.只有case object实现者的sealed trait的特殊情况或多或少是枚举的 Scala 版本。

  • It can act as evidence for implicit -driven logic.它可以作为implicit驱动逻辑的证据。

  • It introduces a singleton type.它引入了单例类型。

It's a very powerful and general construct.这是一个非常强大和通用的构造。 What can be very confusing to Scala beginners is that the same construct can have vastly different uses. Scala 初学者可能会感到非常困惑的是,相同的构造可能有截然不同的用途。 And an object can serve many of these different uses all at once, which can be even more confusing.一个object可以同时用于许多这些不同的用途,这可能会更加混乱。

The formal difference -形式上的区别——

  1. you can not provide constructor parameters for Objects您不能为对象提供构造函数参数
  2. Object is not a type - you may not create an instance with new operator.对象不是类型 - 您不能使用 new 运算符创建实例。 But it can have fields, methods, extend a superclass and mix in traits.但它可以有字段、方法、扩展超类和混合特征。

The difference in usage:用法上的区别:

  • Scala doesn't have static methods or fields. Scala 没有静态方法或字段。 Instead you should use object .相反,您应该使用object You can use it with or without related class.您可以在有或没有相关类的情况下使用它。 In 1st case it's called a companion object.在第一种情况下,它被称为伴随对象。 You have to:你必须:
    1. use the same name for both class and object对类和对象使用相同的名称
    2. put them in the same source file.将它们放在同一个源文件中。
  • To create a program you should use main method in object , not in class .要创建程序,您应该在object使用 main 方法,而不是在class

     object Hello { def main(args: Array[String]) { println("Hello, World!") } }
  • You also may use it as you use singleton object in java.您也可以像在 java 中使用单例对象一样使用它。



The object keyword creates a new singleton type, which is like a class that only has a single named instance. object关键字创建一个新的单型,这就好比一个只有一个命名实例。 If you're familiar with Java, declaring an object in Scala is a lot like creating a new instance of an anonymous class.如果您熟悉 Java,那么在 Scala 中声明一个对象很像创建一个匿名类的新实例。

Scala has no equivalent to Java's static keyword, and an object is often used in Scala where you might use a class with static members in Java. Scala 没有与 Java 的static关键字等效的关键字,并且在 Scala 中经常使用对象,您可能会在 Java 中使用具有静态成员的类。

Object is a class but it already has(is) an instance, so you can not call new ObjectName . Object是一个类,但它已经有(是)一个实例,所以你不能调用new ObjectName On the other hand, Class is just type and it can be an instance by calling new ClassName() .另一方面, Class只是类型,它可以通过调用new ClassName()成为一个实例。

In scala, there is no static concept.在Scala中,没有static概念。 So scala creates a singleton object to provide entry point for your program execution.所以 scala 创建了一个单例对象来为你的程序执行提供入口点。 If you don't create singleton object, your code will compile successfully but will not produce any output.如果您不创建单例对象,您的代码将成功编译但不会产生任何输出。 Methods declared inside Singleton Object are accessible globally.在单例对象中声明的方法可以全局访问。 A singleton object can extend classes and traits.单例对象可以扩展类和特征。

Scala Singleton Object Example 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")  
    }  
}  

Output:输出:

Hello, This is Singleton Object

In scala, when you have a class with same name as singleton object, it is called companion class and the singleton object is called companion object.在scala中,当你有一个与单例对象同名的类时,它被称为伴生类,而单例对象被称为伴生对象。

The companion class and its companion object both must be defined in the same source file.伴生类及其伴生对象都必须在同一个源文件中定义。

Scala Companion Object Example 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.")  
    }  
}  

Output:输出:

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

In scala, a class can contain:在 Scala 中,一个类可以包含:

1. Data member 1. 数据成员

2. Member method 2.会员方式

3. Constructor Block 3. 构造块

4. Nested class 4. 嵌套类

5. Super class information etc. 5.超级班信息等。

You must initialize all instance variables in the class.您必须初始化类中的所有实例变量。 There is no default scope.没有默认范围。 If you don't specify access scope, it is public.如果您不指定访问范围,则它是公开的。 There must be an object in which main method is defined.必须有一个定义了 main 方法的对象。 It provides starting point for your program.它为您的程序提供了起点。 Here, we have created an example of class.在这里,我们创建了一个类的例子。

Scala Sample Example of Class类的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);  
    }  
} 

I am sorry, I am too late but I hope it will help you.对不起,我来晚了,但我希望它会帮助你。

对象在某种程度上类似于Java中的静态类,静态特性意味着静态类在放入JVM时不需要创建对象,可以直接使用类名和相同的实例(相同的数据状态) ) 在任何使用它的地方共享。

Scala class same as Java Class but scala not gives you any entry method in class, like main method in java. Scala 类与 Java 类相同,但 Scala 没有为您提供类中的任何入口方法,例如 java 中的 main 方法。 The main method associated with object keyword.与 object 关键字关联的主要方法。 You can think of the object keyword as creating a singleton object of a class that is defined implicitly.您可以将 object 关键字视为创建隐式定义的类的单例对象。

more information check this article class and object keyword in scala programming更多信息请查看本文在Scala编程中的类和对象关键字

A class is just like any other class in other languages.一个类就像其他语言中的任何其他类一样。 You define class just like any other language with some syntax difference.您可以像定义任何其他语言一样定义类,但存在一些语法差异。

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

However, object is a class with single object only.但是, object 是一个只有单个对象的类。 This makes it interesting as it can be used to create static members of a class using companion object .这使它变得有趣,因为它可用于使用伴生对象创建类的静态成员。 This companion object has access to private members of the class definition and it has the same name as the class you're defining.这个伴随对象可以访问类定义的私有成员,并且它与您定义的类具有相同的名称。

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()

Also, noteworthy point is that object class is lazily created which is another important point.另外,值得注意的一点是对象类是惰性创建的,这是另一个重要的点。 So, these are not instantiated unless they are needed in our code.因此,除非在我们的代码中需要它们,否则不会实例化它们。

If you're defining connection creation for JDBC, you can create them inside object to avoid duplication just like we do in Java with singleton objects.如果您正在为 JDBC 定义连接创建,您可以在对象内部创建它们以避免重复,就像我们在 Java 中使用单例对象所做的那样。

If you are coming from java background the concept of class in scala is kind of similar to Java, but class in scala cant contain static members.如果您来自 Java 背景,Scala 中类的概念与 Java 有点相似,但 Scala 中的类不能包含静态成员。

Objects in scala are singleton type you call methods inside it using object name, in scala object is a keyword and in java object is a instance of class scala 中的对象是单例类型,您使用对象名称在其中调用方法,scala 中的对象是关键字,而 java 中的对象是类的实例

Class & object: a class is a definition which describes all attributes of entity or an object. 类和对象:类是一个定义,它描述实体或对象的所有属性。 And object is an instance of a class. 对象是类的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM