스칼라에서 객체와 클래스의 차이점


635

인터넷에서 일부 스칼라 튜토리얼을 살펴보고 예제의 시작 부분에 객체가 선언되어 있음을 알았습니다.

스칼라 class와 의 차이점은 무엇입니까 object?

답변:


578

tl; dr

  • class C Java 또는 C ++에서와 같이 클래스를 정의합니다.
  • object O익명 클래스의 인스턴스로 싱글 톤 객체 O를 만듭니다 . 일부 클래스의 인스턴스와 연관되지 않은 정적 멤버를 보유하는 데 사용할 수 있습니다.
  • object O extends T객체 O를 인스턴스로 만든다 trait T; 그런 다음 O어디든지 통과 할 수 있습니다 T.
  • 가있는 경우 class C, 다음 object C은 IS 동반자 객체 클래스는 C; 컴패니언 개체는 자동으로의 인스턴스 가 아닙니다C .

objectclass에 대한 Scala 설명서도 참조하십시오 .

object 정적 멤버의 호스트로서

가장 object먼저 클래스의 인스턴스를 먼저 인스턴스화하지 않고도 사용할 수있는 메소드 및 값 / 변수를 보유해야합니다. 이 사용은 staticJava 멤버 와 밀접한 관련이 있습니다 .

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

그런 다음을 사용하여 위의 메소드를 호출 할 수 있습니다 A.twice(2).

twice어떤 클래스의 멤버 라면 A먼저 인스턴스를 만들어야합니다.

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

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

twice인스턴스 별 데이터가 필요하지 않으므로 이것이 얼마나 중복되는지 확인할 수 있습니다 .

object 특별한 명명 된 인스턴스로서

또한 object클래스 나 특성의 특수 인스턴스로 자체를 사용할 수도 있습니다 . 이렇게하면 trait서브 클래스의 인스턴스가되기 위해 오브젝트를 확장해야 합니다.

다음 코드를 고려하십시오.

object A extends B with C {
  ...
}

이 선언은 첫째을 모두 확장 익명 (액세스) 클래스 선언 BC및 명명 된이 클래스의 단일 인스턴스를 인스턴스화합니다 A.

이 방법은 A형식의 개체 기대 함수에 전달 될 수있다 B거나 C, 또는 B with C.

추가 기능 object

스칼라에는 객체의 특별한 기능이 있습니다. 공식 문서 를 읽는 것이 좋습니다 .

  • def apply(...) 일반적인 메소드 이름없는 구문을 가능하게합니다. A(...)
  • def unapply(...)맞춤 패턴 일치 추출기 를 만들 수 있습니다
  • 동일한 이름의 클래스를 수반하는 경우, 객체는 암시 적 매개 변수를 해석 할 때 특별한 역할을 담당합니다.

38
또한 클래스 A를 정의하고 오브젝트 A의 모든 메소드를 클래스 A의 정적 메소드 (Java와의 인터페이스)로 작성합니다. (Sdala 2.8에서 수정 된 Scala 2.7의 버그 Modulo)
Ken Bloom

2
@KenBloom 정말? scala> Commerce res8 : Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console> : 23 : 오류 : 찾을 수 없음 : type Commerce classOf [Commerce] ^ scala> new Commerce < console> : 23 : 오류 : 찾을 수 없음 : 유형 Commerce new Commerce ^
Hendy Irawan

3
@Hendy : 스칼라는 Commerce클래스를 인식하지 못하지만 JVM과 Java 언어는 인식합니다 . (그래서 object Foo{ def main(args:Seq[String]) }프로그램을 실행할 수 있고 기대할 수 있습니다 .)
Ken Bloom

3
내가 ziggystar의 답변이 더 정확하다고 생각 상공라는 이름의 해당 클래스가 명시 적으로 정의되지 않는 한, 클래스가 익명 클래스입니다 (다음 상거래 객체는 상업 클래스에 동반자 객체가 될 것입니다)
Hendy 이르 완

3
@DavidApltauer 내 대답에 포함되지 않은 미묘한 부분이 충분하다고 확신합니다. 그러나이 내용을 읽는 대부분의 사람들에게는 문제가되지 않을 것입니다. 그리고 나는 어떤 특성의 실체로서 개체를 전달하는 데 아무런 문제가 없었습니다. 그러나 작동해야합니다.
ziggystar

249

A class는 정의, 설명입니다. 다른 유형의 방법 및 구성 측면에서 유형을 정의합니다.

object고유 보장하는 클래스의 인스턴스 - 싱글이다. 모든 object코드에 대해 익명 클래스가 생성되며,이 클래스는 object구현하기로 선언 한 클래스에서 상속됩니다 . 이 클래스는 스칼라 소스 코드에서 볼 수 없지만 리플렉션을 통해 얻을 수는 있습니다.

사이의 관계가있다 object하고 class. 객체가 동일한 이름을 공유하는 경우 클래스의 동반 객체라고합니다. 이런 일이 발생하면 각각은 서로의 private가시성에 접근 할 수 있습니다 . 그러나 이러한 방법은 자동으로 가져 오지 않습니다. 명시 적으로 가져 오거나 클래스 / 개체 이름으로 접두사를 붙여야합니다.

예를 들면 다음과 같습니다.

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

1
귀찮게해서 죄송하지만, 메소드를 컴패니언 객체로 가져 오는 방법이나 접두사를 붙이는 방법에 대한 예를들 수 있습니까?
ithkuil

4
@ithkuil 완료. 어리석은 예에 대해 유감스럽게도, 나는 짧고 좋은 것을 생각할 수 없었습니다.
Daniel C. Sobral

Object에서 클래스 메소드를 사용하려면 어떻게해야합니까? 가능할까요? 클래스의 메서드가 있고 Object에서 사용하려는 경우 클래스를 가져 오려고하면 사용할 수 없습니다. 결국에는 생성자를 만들고 메서드를 호출해야합니다. 따라서 컴패니언 객체를 만들어 가져 오기를 사용하여 객체의 메소드에 액세스 할 수 있지만 그 반대의 경우는 불가능합니다. 누군가가 확인을 할 수 있습니까?
piyushGoyal

@piyushGoyal 사실이 아닙니다. 객체에 메소드가 있다고 가정하면 , 컴패니언 클래스의 def f(x: X) = ???private 메소드를 호출 할 수 있습니다 . xX
Daniel C. Sobral

함수에 전달 된 X는 클래스 XI의 인스턴스입니다. 그렇다면 결국 객체 x를 사용하여 def f에서 X 클래스의 메서드를 호출하는 것입니다. 맞습니까?
piyushGoyal

76

객체에는 정확히 하나의 인스턴스가 있습니다 (호출 할 수 없음 new MyObject). 한 클래스의 인스턴스를 여러 개 가질 수 있습니다 .

Object는 Java의 정적 메소드 및 필드 와 동일한 (및 일부 추가) 목적 으로 사용 됩니다.


19

많은 사람들이 설명했듯이 object싱글 톤 인스턴스를 정의합니다. 내가 여기에 대답에서 제외 한 것은 object몇 가지 목적 을 제공 한다는 것입니다 .

  • 정적 메소드 또는 편의 메소드로 간주되는 것을 포함 하는 class/ 의 동반자 오브젝트 trait가 될 수 있습니다.

  • 관련 / 자회사 유형 및 정의 등을 포함하는 모듈처럼 작동 할 수 있습니다.

  • class하나 이상의 traits를 확장하여 인터페이스를 구현할 수 있습니다 .

  • sealed trait데이터가없는 경우를 나타낼 수 있습니다 . 이와 관련하여 종종 case class매개 변수가없는 a보다 더 올바른 것으로 간주됩니다 . 구현 sealed trait자만 있는 특수한 경우 case object는 스칼라 버전의 열거 형입니다.

  • implicit논리 기반 논리의 증거로 작용할 수 있습니다 .

  • 싱글 톤 타입을 소개합니다.

매우 강력하고 일반적인 구성입니다. 스칼라 초보자에게 매우 혼란 스러울 수있는 것은 동일한 구성이 크게 다른 용도를 가질 수 있다는 것입니다. 그리고 object한 번에 이러한 여러 가지 용도를 모두 제공 할 수 있으므로 훨씬 더 혼란 스러울 수 있습니다.


18

스칼라에서 객체를 정의하는 것은 정적 메소드 만있는 Java에서 클래스를 정의하는 것과 같습니다. 그러나 스칼라에서 객체는 다른 수퍼 클래스를 확장하고 인터페이스를 구현하며 마치 클래스의 인스턴스 인 것처럼 전달 될 수 있습니다. (따라서 클래스의 정적 메소드와 비슷하지만 더 좋습니다).


17

공식적인 차이점-

  1. 객체에 생성자 매개 변수를 제공 할 수 없습니다
  2. 객체 가 유형이 아니므로 new 연산자로 인스턴스를 만들 수 없습니다. 그러나 필드, 메소드, 수퍼 클래스를 확장하고 특성을 혼합 할 수 있습니다.

사용법의 차이 :

  • 스칼라에는 정적 메소드 또는 필드가 없습니다. 대신을 사용해야합니다 object. 관련 클래스 유무에 관계없이 사용할 수 있습니다. 첫 번째 경우에는 컴패니언 객체라고합니다. 당신은해야합니다 :
    1. 클래스와 객체에 같은 이름을 사용하십시오
    2. 그것들을 같은 소스 파일에 넣으십시오.
  • 프로그램을 만들려면에있는 object것이 아니라에서 주요 방법을 사용해야합니다 class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Java에서 싱글 톤 객체를 사용할 때 사용할 수도 있습니다.

      
        
      


"객체에 대해 생성자 매개 변수를 제공 할 수 없습니다."개체에는 생성자처럼 작동하는 apply (...) 메소드가 있습니다. 이것은 나를 조금 혼란스럽게합니다.
Danielle

7

객체의 키워드는 같이하는 새로운 싱글 타입 생성 클래스 단 하나의 명명 된 인스턴스가 있습니다. Java에 익숙하다면 Scala 에서 객체 를 선언하는 것은 익명 클래스의 새 인스턴스를 만드는 것과 비슷합니다.

스칼라는 자바의 정적 키워드 와 동일하지 않으며 , 스칼라에서 객체 는 종종 스칼라에서 정적 멤버가있는 클래스를 Java에서 사용할 수있는 곳에서 사용됩니다.


6

객체 는 클래스이지만 이미 인스턴스가 있으므로 호출 할 수 없습니다 new ObjectName. 반면에 Class 는 그냥 타입이며을 호출하여 인스턴스가 될 수 있습니다 new ClassName().


4

스칼라에는 static개념 이 없습니다 . 스칼라는 프로그램 실행을위한 진입 점을 제공하는 단일 객체를 만듭니다. 싱글 톤 객체를 만들지 않으면 코드가 성공적으로 컴파일되지만 출력이 생성되지 않습니다. Singleton Object 내에 선언 된 메소드는 전 세계적으로 액세스 할 수 있습니다. 싱글 톤 객체는 클래스와 특성을 확장 할 수 있습니다.

스칼라 싱글 톤 객체 예

object Singleton{  
    def main(args:Array[String]){  
        SingletonObject.hello()         // No need to create object.  
    }  
}  


object SingletonObject{  
    def hello(){  
        println("Hello, This is Singleton Object")  
    }  
}  

산출:

Hello, This is Singleton Object

스칼라에서는 싱글 톤 객체와 이름이 같은 클래스가 있으면 컴패니언 클래스라고하며 싱글 톤 객체를 컴패니언 객체라고합니다.

컴패니언 클래스와 해당 컴패니언 오브젝트는 모두 동일한 소스 파일에 정의되어야합니다.

스칼라 컴패니언 객체 예

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.")  
    }  
}  

산출:

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

스칼라에서 클래스는 다음을 포함 할 수 있습니다.

1. 데이터 멤버

2. 회원 방법

3. 생성자 블록

4. 중첩 클래스

5. 슈퍼 클래스 정보 등

클래스의 모든 인스턴스 변수를 초기화해야합니다. 기본 범위는 없습니다. 액세스 범위를 지정하지 않으면 공개 범위입니다. 기본 메소드가 정의 된 오브젝트가 있어야합니다. 프로그램의 시작점을 제공합니다. 여기에서 클래스 예제를 만들었습니다.

스칼라 샘플 클래스 예제

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

죄송합니다. 너무 늦었지만 도움이 되길 바랍니다.


2

스칼라 클래스는 Java 클래스와 동일하지만 스칼라는 Java의 기본 메소드와 같이 클래스의 엔트리 메소드를 제공하지 않습니다. 객체 키워드와 관련된 주요 방법. object 키워드는 암시 적으로 정의 된 클래스의 단일 객체를 만드는 것으로 생각할 수 있습니다.

자세한 내용 은 스칼라 프로그래밍 에서이 기사 클래스와 객체 키워드를 확인하십시오.


2

객체는 Java의 정적 클래스와 비슷하며 정적 특성은 정적 클래스가 JVM에 넣을 때 객체를 만들 필요가 없음을 의미하며 클래스 이름과 동일한 인스턴스 (동일한 데이터 상태)에서 사용할 수 있습니다 )은 사용되는 곳마다 공유됩니다.


1

수업은 다른 언어의 다른 수업과 같습니다. 구문 차이가있는 다른 언어와 마찬가지로 클래스를 정의합니다.

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

그러나 객체는 단일 객체 만있는 클래스입니다. companion 객체를 사용하여 클래스의 정적 멤버를 만드는 데 사용할 수 있으므로 흥미 롭습니다 . 이 컴패니언 객체는 클래스 정의의 비공개 멤버에 액세스 할 수 있으며 정의한 클래스와 이름이 같습니다.

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에서와 같이 복제를 피하기 위해 오브젝트 내부에서 작성할 수 있습니다.


0

Java 배경에서 오는 경우 scala의 클래스 개념은 Java와 비슷하지만 scala의 클래스에는 정적 멤버가 포함되어 있지 않습니다.

스칼라의 객체는 객체 이름을 사용하여 내부에서 메소드를 호출하는 싱글 톤 유형입니다. 스칼라에서 객체는 키워드이며 Java 객체에서는 클래스의 인스턴스입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.