【问题标题】:Understanding class and object in scala理解scala中的类和对象
【发布时间】:2016-10-17 17:20:01
【问题描述】:

我对 scala 很陌生,现在我必须从事一个用 scala 和 java 编写的项目。我遇到了这样的结构:

class SomeType{
    //...
}

trait Trait1 extends scala.AnyRef{
}

trait Trait2 extends extends scala.AnyRef{
}

class MyClass(arg : SomeType) extends Trait1{
    //...
}

object MyClass extends Trait2{
    //...
}

这有点让人麻木。据我通过阅读answer 得到的,我们可以将objects 视为具有抽象方法的类。 IE。我们可以(在我看来)在 java 中使用Class<T> 对象定义一些映射。

但在此示例中,classobject 扩展了 不同 traits。这就是我真正感到困惑的地方。我无法想象它的含义以及使用它的原因。

【问题讨论】:

  • 你的问题到底是什么?
  • 我们不能将对象视为具有抽象方法的类。对象只是单例。
  • 对于 jvm 对象(不完全是)一个常规类,比如说SomeObject。但是 scala 还会生成另一个静态值包含 instance = new SomeClass() 的类,因此当您访问 SomeObject.someMethod 时,您实际上是在调用 instance.someMethod
  • 您引用的答案说将对象视为“隐式定义的类的单例”。也就是说,它也是一个对象。也许以下链接会对您有所帮助:docs.scala-lang.org/tutorials/tour/singleton-objects.html。最值得注意的是它说'scala中没有静态关键字'。所以对象在java程序员认为静态的地方被使用..为什么有区别?他们来自不同的思想流派。 Scala 深受 Haskell 的影响,Java 深受 C/C++ 的影响。

标签: java scala


【解决方案1】:

我将尝试从了解 Java 的人的角度解释什么是 Scala object

在Java 中,您可以定义“普通”类成员和static 类成员。当某事物(例如成员变量)在 Java 中为 static 时,则该成员变量只有一个实例,该实例由该类的所有实例共享。

在 Scala 中,没有 static。与 Java 相比:无论你在 Java 中创建 static,你都会在 Scala 中添加 object

Scala object 是一个单例 - 它只有一个实例,就像 Java 中的 static 成员只有一个实例一样。

我希望这能让我们更清楚 Scala object 到底是什么。

Scala object 可以像任何其他类或特征一样扩展类或特征,因此它继承在它扩展的类或特征中定义的任何内容。真的没有理由不应该这样做。

请注意,如果您有一个同名的class 和一个object,那么这两个属于一起 - 他们可以看到彼此的私人成员。 object 被称为类的伴生对象

请注意,这意味着object 是该类的一个实例。它不是——它是一个独立的东西,站在班级旁边。也许您对扩展不同特征的类和对象的困惑来自对这一点的误解。

【讨论】:

    【解决方案2】:

    一个类就像其他语言中的任何其他类一样。您定义类就像任何其他具有一些语法差异的语言一样。此外,还有case classes,其中定义了一些方便的方法,并允许轻松初始化对象。

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

    但是,object 是一个只有单个对象的类。这很有趣,因为它可以用于使用 companion object 创建类的静态成员。这个伴生对象可以访问类定义的私有成员,并且它与您定义的类同名。

    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 中使用单例对象所做的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 2011-04-22
      • 2019-01-18
      • 2010-12-17
      • 1970-01-01
      相关资源
      最近更新 更多