Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop Scala中有伴生对象的基本原理是什么?_Oop_Scala_Companion Object - Fatal编程技术网

Oop Scala中有伴生对象的基本原理是什么?

Oop Scala中有伴生对象的基本原理是什么?,oop,scala,companion-object,Oop,Scala,Companion Object,是否存在需要类的伴生对象(单例)的情况?为什么我要创建一个类,比如说Foo,并为它创建一个伴生对象?伴生对象基本上提供了一个可以放置“类似静态”方法的地方。此外,伴随对象或伴随模块可以完全访问类成员,包括私有成员 配套对象非常适合封装工厂方法之类的东西。例如,不必到处都有Foo和FooFactory,您可以让一个带有伴生对象的类承担起工厂的职责。除了Saem在中所说的内容之外,Scala编译器还查找相应伴生对象(源对象或目标对象)中的类型,因此,转换不需要导入 关于单例对象的原因,一般说来: 如

是否存在需要类的伴生对象(单例)的情况?为什么我要创建一个类,比如说
Foo
,并为它创建一个伴生对象?

伴生对象基本上提供了一个可以放置“类似静态”方法的地方。此外,伴随对象或伴随模块可以完全访问类成员,包括私有成员


配套对象非常适合封装工厂方法之类的东西。例如,不必到处都有
Foo
FooFactory
,您可以让一个带有伴生对象的类承担起工厂的职责。

除了Saem在中所说的内容之外,Scala编译器还查找相应伴生对象(源对象或目标对象)中的类型,因此,转换不需要导入

关于单例对象的原因,一般说来:

如第1章所述,Scala比Java更面向对象的一种方式是Scala中的类不能有静态成员。相反,Scala有单例对象(第65页)


…而且它是存储伴随类的静态工厂方法(而不是DP)的好地方。如果您将那些重载的工厂方法命名为apply(/…/),您将能够创建/初始化您的类

  • 没有“新的”(不太重要)

  • 使用不同的可能参数集(与Bloch在有效Java中编写的伸缩构造函数相比)

  • 能够决定要创建哪个派生类而不是抽象类(附带的)

  • 示例代码:

    abstract class AbstractClass;
    class RealThing(s: String) extends AbstractClass;
    class AlternativeThing(i: Int) extends AbstractClass;
    object AbstractClass {
      def apply(s: String) = {
        new RealThing(s)
      }
      def apply(i: Int) = {
        new AlternativeThing(i)
      }
    }
    
    // somewhere else you can
    val vs = AbstractClass("asdf")  // gives you the RealThing wrapped over string
    val vi = AbstractClass(123)  // gives you AlternativeThing wrapped over int
    
    我不会将对象/基类称为AbstractXxxxx,因为它看起来并不坏:就像创建抽象的东西一样。给那些名字一个真正的含义。
    考虑使用不可变的、方法较少的、case类并密封抽象基类。 伴生对象可用于存储类的所有实例所共有的状态和方法,但它们不使用静态方法或字段。它们使用可以通过继承重写的常规虚拟方法。Scala确实没有任何静态特性。有很多方法可以使用它,但这里有一个简单的例子

    abstract class AnimalCounter
    {
        var animals = 0
    
        def name: String
    
        def count()
        {
            animals += 1
            println("%d %ss created so far".format(animals, name))
        }
    }
    
    abstract class Animal
    {
        def companion: AnimalCounter
        companion.count()
    }
    
    object Dog extends AnimalCounter
    {
        val name = "dog"
    }
    
    class Dog extends Animal
    {
        def companion = Dog
    }
    
    object Cat extends AnimalCounter
    {
        val name = "cat"
    }
    
    class Cat extends Animal
    {
        def companion = Cat
    }
    
    这将产生以下输出:

    scala> new Dog
    1 dogs created so far
    
    scala> new Cat
    1 cats created so far
    
    scala> new Dog
    2 dogs created so far
    
    scala> new Cat
    2 cats created so far
    

    我总是将配套对象视为在Scala中编写函数式和面向对象代码的桥梁。很多时候,我们只需要一些纯函数,它们接受一些输入并提供一个处理结果。将这些相关函数放在伴随对象中可以方便地查找和使用,对于我自己以及构建在代码之上的某个人来说都是如此


    此外,它是一种语言提供的特性,可以在不做任何事情的情况下编写singleton模式。当您需要一个单例来封装JVM生命周期中的委托器时,这尤其有用。例如,在Scala中编写一个简单的HTTP客户端库,您可以在其中封装一个底层的基于Java实现的delegator,并让API的使用者生活在纯粹的世界中。

    如果您在同一个文件中用相同的名称定义类和对象,它们称为伴生类和对象。Scala没有将static作为JAVA关键字,您可以用Scala中的伴生类和对象替换static

    有关更多详细信息,请查看文章

    首先,它明确区分了静态方法和非静态方法。还提供了创建单例类的简单方法


    它还可以从其他类和/或特征继承方法,这是Java静态方法无法完成的,并且可以作为参数传递。

    这里也可以找到类似的说明:请参见这里的答案汇编
    RealThing
    AlternativeThing
    类应该有一个
    private
    构造函数来强制用户使用
    AbstractClass
    具有工厂
    class AlternativeThing private(i:Int)扩展了AbstractClass
    @[Szymon Jachem]Scala抽象类不支持多重继承。那么为什么编译器在您的情况下允许它呢?