Programing

Scala에서 컴패니언 객체를 갖는 이유는 무엇입니까?

crosscheck 2020. 8. 18. 07:11
반응형

Scala에서 컴패니언 객체를 갖는 이유는 무엇입니까?


클래스의 컴패니언 객체 (싱글 톤)가 필요한 경우가 있습니까? 왜 내가 클래스 Foo를 만들고이를위한 컴패니언 객체를 만들고 싶습니까?


컴패니언 객체는 기본적으로 "정적 유사"메서드를 넣을 수있는 장소를 제공합니다. 또한 컴패니언 객체 또는 컴패니언 모듈은 private 멤버를 포함하여 클래스 멤버에 대한 전체 액세스 권한을 갖습니다.

컴패니언 객체는 팩토리 메소드와 같은 것을 캡슐화하는 데 좋습니다. 대신 예를 들어,이, 필요로 Foo하고 FooFactory모든 곳에서, 당신은 공장의 책임에 동반자 개체를 포획하여 클래스를 가질 수 있습니다.


컴패니언 객체는 클래스의 모든 인스턴스에 공통적 인 상태 및 메서드를 저장하는 데 유용 하지만 정적 메서드 나 필드를 사용하지 않습니다 . 상속을 통해 재정의 할 수있는 일반 가상 메서드를 사용합니다. 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

... 수반되는 클래스에 대한 정적 팩토리 메서드 (DP가 아님)를 저장하는 것이 좋습니다. 오버로드 된 팩토리 메소드의 이름을 apply (/ ... /)로 지정하면 클래스를 생성 / 초기화 할 수 있습니다.

  1. 'new'없이 (그다지 중요하지 않음)

  2. 다른 가능한 매개 변수 세트 사용 (Bloch가 생성자 텔레 스코핑에 대해 Effective Java에서 작성한 것과 비교)

  3. with the ability to to decide which derived class you want to create instead of the abstract (accompanied) one

Example code:

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

I wouldn't call the object/base class AbstractXxxxx because it doesn't looks bad: like creating something abstract. Give those names a real meaning. Consider using immutable, method less, case classes and seal the abstract base class.


In addition to the things Saem said in his reply, the Scala compiler also looks for implicit conversions of types in the corresponding companion objects (of either the source or the target), so the conversions don't need to be imported.

About the reason for singleton objects in general Programming in Scala says:

As mentioned in Chapter 1, one way in which Scala is more object-oriented than Java is that classes in Scala cannot have static members. Instead, Scala has singleton objects (p. 65).


I always see companion objects as a bridge to write both functional and object oriented code in Scala. Many times we just need pure functions which take some input and provide a processing result. Putting those relevant functions in the companion object makes it easy to look up and use, for myself as well as some one building on top of my code.

Moreover, it is a language provided feature to write the singleton pattern without doing anything. This is especially useful when you need a singleton to encapsulate a delegator for the life of JVM. For example, writing a simple HTTP client library in Scala where you can encapsulate an underlying Java implementation based delegator and let consumers of your API live in pure world.


If you define class and object in same file with same name, they known as companion class and object. Scala don't have static as JAVA keyword, You can take as replacement of static with companion class and object in Scala.

For more detail information please check article class and object keyword in scala programming


At first, it provides a clear separation of static vs non static methods methods.Also provide a simple way to create singleton class.

It also can inherit methods from other classes and/or traits, which cannot be done with Java static methods.and can be passed as a parameter.

참고URL : https://stackoverflow.com/questions/609744/what-is-the-rationale-behind-having-companion-objects-in-scala

반응형