본문 바로가기

Programming Language/Java & Scala

자바와 스칼라 차이점

728x90

자바와 스칼라 둘다 JVM위에서 돌아간다는 공통점이 있다. 그러나 객체지향적 언어와 함수형 언어라는 점이 매우 다르다. 어떤 다른점이 있는지 개략적으로 살펴보자.

 

TRAIT

스칼라의 trait는 자바의 인터페이스와 유사한 역할을 한다. 스칼라에서는 interface가 없다. trait는 변수를 선언하고 메서드를 구현할 수 있다는 점이 인터페이스와 차이점이다. 물론 자바 8부터는 인터페이스에서 default 메서드형태로 구현할 수 있는 점이 동일하다. 그러나 자바8의 인터페이스는 변수를 선언할 수 없고 메서드만 선언할 수 있기 때문에 trait와 차별점을 가진다고 볼수 있다. 그럼 추상클래스와 비슷하다고 볼 수 있지 않을까? 자바의 추상클래스는 2개 이상 상속가능하고 trait도 클래스에 2개 이상의 trait를 상속할 수 있다. 하지만 추상클래스는 trait와 다르게 변수의 상태를 가질 수 없다. 즉 trait는 변수를 초기화하여 사용가능하다. 

 

정리하자면 trait는 자바의 인터페이스와 추상클래스의 장점을 섞었다고 볼 수 있다. 

 

TUPLE

튜플은 여러 객체를 하나의 묶음으로 표현한 자료구조형이다. 객체를 콤마로 넣어주어 타입을 선언하는데 따로 객체의 형을 정해주지 않더라도 자동으로 설정한다. 튜플로 선언하는 방법은 다음과 같다.

val myTuple = (13,"wonyoung")

튜플에서 원소에 접근하기 위해서는 다음과 같이 수행할 수 있다.

val myTuple = (13,"wonyoung")
println(myTuple._1) # 13

주의해야할점은 튜플의 시작 숫자는 0이 아닌 1이다.

var VS val VS def

스칼라에서는 변수를 var 또는 val로 선언할 수 있다. var은 변수 개념으로 변할 수 있는 값이고, val은 변하지 않는 값이다. val로 선언할 경우 다른 값을 대입하면 컴파일에러가 발생한다.

 

def는 메서드를 선언하는데 사용된다. 재밌는 점은 def로 선언한 메서드를 1급 함수로 사용할 수 있다는 점이다. 1급 함수(first class function)이라는 말은 최상위 객체라는 뜻이다. 

object Hello {

  def callByValue(x: Int) = {
    println("first=" + x)
    println("second=" + x)
  }

  def callByName(x: => Int) = {
    println("first=" + x)
    println("second=" + x)
  }

  def firstMethod() = {
    println("call first Method")
    1
  }

  def main(args: Array[String]) = {
    callByValue(firstMethod())
    callByName(firstMethod())
  }
}

//call first Method
//first=1
//second=1
//call first Method
//first=1
//call first Method
//second=1

여기서 재밌는점은 => 을 미사용/사용에 따라 다른 결과값을 내주고 있다. =>를 사용한 경우는 firstMethod() 함수가 그대로 전달되어 각 print마다 해당 메서드가 호출되었다는 점이다.

CASE CLASS

자바에서 VO(Value Object)형태의 데이터를 담는 자료형을 사용하기 위해 getter, setter가 선언된 클래스를 선언하곤 했다. VO가 많아질수록 클래스는 더 늘어나게되고 내부에서 사용되는 setter, getter의 코드는 더더욱 늘어났다. 스칼라에서는 case class로 이러한 낭비를 줄일 수 있다. case class도 클래스이므로 trait 또는 다른 클래스에서 상속받아 사용할 수 있다.

object Hello {
  case class Student(name: String, age: Int)
  def main(args: Array[String]) = {
    val wonyoung = Student("wonyoung", 30)
    println(wonyoung.name)
  }
}

 

728x90