클래스와 메서드
클래스 생성자
클래스의 인스턴스를 만드는 생성자(constructor)
자바 클래스 생성자
public class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return String.format("%s님은 %d세입니다.", name, age);
}
}
자바에서는, 클래스명과 같은 이름으로 생성자를 만듭니다. 하위 클래스에서 상위 클래스의 메서드를 재정의할 때,@Override
애너테이션을 써서 명시하면 좋습니다.
스칼라 클래스 기본 생성자
class Person(val name: String, val age: Int) {
override def toString = s"${name}님은 ${age}세입니다."
}
스칼라에서는 클래스 이름 바로 뒤에 이어서, 주 생성자에 전달할 파라미터를 선언하는 방식으로 씁니다. 여기에, val
이나 var
로 받은 파라미터들은 그대로 인스턴스 변수(필드)가 됩니다.
메서드를 재정의하려면, 자바에서는 선택적으로 @Override
애너테이션을 쓰고, 스칼라에서는 override
키워드를 필수로 써야 합니다.
그리고, 자바에서는 어떤 이름(identifier) 앞에 타입을 선언하고, 스칼라에서는 이름 뒤에 타입을 명시합니다.
클래스 보조 생성자
주 생성자 말고도, 보조 생성자를 사용해 클래스 인스턴스를 만들 수 있습니다.
자바 클래스 보조 생성자
public class Person {
public String name;
public int age;
// 주 생성자 (primary constructor)
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 인수 없는 생성자
public Person() {
this("", 0);
}
// 인수 하나 받는 생성자
public Person(String name) {
this(name, 0);
}
@Override
public String toString() {
return String.format("%s님은 %d세입니다.", name, age);
}
}
자바에서는 클래스명과 같은 이름으로, 파라미터가 다른 생성자를 여럿 작성해서 씁니다.
스칼라 클래스 보조 생성자
class Person(var name: String, var age: Int) {
// 인수 없는 보조 생성자
def this() = this("", 0)
// 인수 하나 받는 보조 생성자
def this(name: String) = this(name, 0)
override def toString = s"${name}님은 ${age}세입니다."
}
스칼라에서 생성자를 추가하려면, this
라는 이름으로 보조 생성자를 메서드처럼 작성합니다.
한 줄 메서드
자바
public int add(int a, int b) {
return a + b;
}
스칼라
def add(a: Int, b: Int): Int = a + b
스칼라에서는 메서드 본문을 한 줄로 이어 쓸 수 있으며, return
키워드 없이도, 최종 평가식이 메서드의 결괏값으로 반환됩니다. 함수 선언부와 본문 사이에 =
기호가 있습니다. 위 add
메서드는, 본문이 단 하나의 식이며, 한 줄로 작성했습니다.
여러 줄 메서드
자바
public double triangle(double a, double b) {
double a2 = a * a;
double b2 = b * b;
return Math.sqrt(a2 + b2);
}
// triangle(3.0, 4.0) => 5.0
스칼라
def triangle(a: Double, b: Double): Double = {
val a2 = a * a
val b2 = b * b
Math.sqrt(a2 + b2)
}
스칼라에서도 중괄호({}
)로 묶어서 여러 줄짜리 메서드 본문을 선언합니다. 따로 return
키워드를 쓰지 않고도, 마지막 식의 결괏값이 메서드의 반환값이 된다는 점이 다릅니다.
필드 변수
자바
final int i = 1;
i = 2; // => 컴파일 에러
자바에서 변수를 만들고, 이후 변경을 막으려면 final
키워드를 붙입니다.
스칼라
val i = 1
i = 2 // => 컴파일 에러
스칼라에서는 val
키워드로 시작해 변수를 만들면, 이후에 값을 바꿀 수 없습니다. 타입을 명시하지 않으면, 스칼라 컴파일러가 적절한 타입을 추론(type inference)합니다. 위 예제의 경우, 변수 i
에 대입하는 값이 1
이고, 이 값의 기본 타입은 Int
이기에, 변수 i
의 타입은 Int
로 추론됩니다.
자바
int i = 1;
var j = 1;
i = 2; // => 변경 가능
j = 3; // => 변경 가능
자바에서 변수는 기본적으로 변경 가능합니다. 자바 10에 추가된 var
키워드를 쓰면, 타입 선언을 생략할 수 있습니다.
스칼라
var i = 1
i = 2 // => 변경 가능
스칼라에서 변경 가능한 변수를 만들려면 var
키워드를 써서 변수를 선언합니다.
정적(static) 메서드
자바
public class StringUtils {
public static boolean isNullOrEmpty(String s) {
return s == null || s.trim().isEmpty();
}
}
자바에서, 정적 static
메서드나 필드는 선언된 클래스들이 공유하게 됩니다. 그리고 public
멤버인 경우 외부에서 곧바로 접근할 수 있습니다.
스칼라
object StringUtils {
def isNullOrEmpty(s: String): Boolean =
s == null || s.trim.isEmpty
}
스칼라에서는 클래스 안에 static
으로 메서드나 필드를 선언하지는 않고, 오브젝트(object
)를 사용합니다. 오브젝트로 만들면 단일(singleton) 인스턴스가 준비되며, 오브젝트 안에 있는 메서드나 필드는, 마치 자바의 static 멤버들처럼 접근해 쓸 수 있습니다.