클래스의 컴패니언 객체 (싱글 톤)가 필요한 경우가 있습니까? 왜 내가 클래스 Foo
를 만들고이를위한 컴패니언 객체를 만들고 싶습니까?
클래스의 컴패니언 객체 (싱글 톤)가 필요한 경우가 있습니까? 왜 내가 클래스 Foo
를 만들고이를위한 컴패니언 객체를 만들고 싶습니까?
답변:
컴패니언 객체는 클래스의 모든 인스턴스에 공통적 인 상태 및 메서드를 저장하는 데 유용 하지만 정적 메서드 나 필드를 사용하지 않습니다 . 상속을 통해 재정의 할 수있는 일반 가상 메서드를 사용합니다. 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 (/ ... /)로 지정하면 클래스를 생성 / 초기화 할 수 있습니다.
'new'없이 (그다지 중요하지 않음)
다른 가능한 매개 변수 세트 사용 (Bloch가 생성자 텔레 스코핑에 대해 Effective 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는 나쁘지 않기 때문에 호출하지 않습니다. 마치 추상적 인 것을 만드는 것과 같습니다. 그 이름에 진정한 의미를 부여하십시오. 불변, 메소드 덜, 케이스 클래스 사용을 고려하고 추상 기본 클래스를 봉인하십시오.
RealThing
그리고 AlternativeThing
클래스는해야 private
(가) 사용하는 사용자를 강제로 생성자 AbstractClass
의 공장을 가지고 있습니다. class AlternativeThing private(i: Int) extends AbstractClass
저는 항상 컴패니언 객체를 스칼라에서 기능적 코드와 객체 지향 코드를 작성 하는 다리 로 간주합니다 . 많은 경우 입력을 받아 처리 결과를 제공하는 순수 함수가 필요합니다. 이러한 관련 함수를 동반 객체에 배치하면 내 코드 위에 빌드하는 것뿐만 아니라 나 자신을 위해 쉽게 찾고 사용할 수 있습니다.
또한 아무것도하지 않고 싱글 톤 패턴을 작성할 수있는 언어 제공 기능입니다. 이것은 JVM의 수명 동안 위임자를 캡슐화하기 위해 싱글 톤이 필요할 때 특히 유용합니다. 예를 들어 기본 Java 구현 기반 위임자를 캡슐화하고 API 소비자가 순수한 세상에 살도록 할 수있는 Scala에서 간단한 HTTP 클라이언트 라이브러리를 작성합니다.
같은 파일에 동일한 이름으로 클래스와 객체를 정의하면 컴패니언 클래스와 객체라고합니다. Scala는 JAVA 키워드로 static이 없습니다. Scala에서 static을 동반 클래스 및 객체로 대체 할 수 있습니다.
자세한 내용 은 스칼라 프로그래밍의 기사 클래스 및 객체 키워드 를 확인하십시오.