Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행하고 있다.


6장

생성자

주 생성자

class Rational(n: Int, d: Int)
  • 클래스 파라미터 : n, d

주 생성자 코드

  • 클래스 내부에 있으면서 필드나 메소드 정의에 들어 있지 않은 코드는 주 생성자에 들어감
class Rational(n: Int, d: Int) {
    println("Created "+ n +"/"+d)
}

toString 메소드 오버라이드

class Rational(n: Int, d: Int) {
    override def toString = n +"/"+ d
}

전제 조건 확인

  • require 문 사용
  • 인자가 false 이면 IllegalArgumentException 예외 발생
class Rational(n: Int, d: Int) {
    require(d != 0)
    override def toString = n +"/"+ d
}

공개 필드

class Rational(n: Int, d: Int) {
    require(d != 0)
    val numer: Int = n
    val denom: Int = d
    override def toString = n +"/"+ d
    def add(that: Rational): Rational =
        new Rational(
            numer * that.denom + that.numer * denom,
            denom * that.denom
        )
}
  • 파라미터 필드(10.6절)를 사용하면 간단하게 작성 가능

자기 참조

  • this
def lessThan(that: Rational) =
    this.numer * that.denom < that.numer * this.denom // this 생략 가능
def max(that: Rational) =
    if (this.lessThan(that)) that else this // lessThan 앞의 this는 생략 가능

보조 생성자

  • def this(...) 으로 시작
class Rational(n: Int, d: Int) {
    require(d != 0)
    val numer: Int = n
    val denom: Int = d
    def this(n: Int) = this(n, 1) // 보조 생성자
    override def toString = n +"/"+ d
    def add(that: Rational): Rational =
        new Rational(
            numer * that.denom + that.numer * denom,
            denom * that.denom
        )
}

비공개 필드, 메소드

class Rational(n: Int, d: Int) {
    require(d != 0)
    private val g = gcd(n.abs, d.abs) // 비공개 필드
    val numer: Int = n / g // 초기화 코드
    val denom: Int = d / g // 초기화 코드
    def this(n: Int) = this(n, 1)
    override def toString = n +"/"+ d
    def add(that: Rational): Rational =
        new Rational(
            numer * that.denom + that.numer * denom,
            denom * that.denom
        )
    private def gcd(a: Int, b: Int): Int = // 비공개 메소드
        if (b == 0) a else gcd(b, a % b)
}

연산자 메소드

class Rational(n: Int, d: Int) {
    require(d != 0)
    private val g = gcd(n.abs, d.abs)
    val numer: Int = n / g
    val denom: Int = d / g
    def this(n: Int) = this(n, 1)
    override def toString = n +"/"+ d
    def + (that: Rational): Rational = // 덧셈 연산자 정의
        new Rational(
            numer * that.denom + that.numer * denom,
            denom * that.denom
        )
    def * (that: Rational): Rational = // 곱셈 연산자 정의
        new Rational(numer * that.numer, denom * that.denom)
    private def gcd(a: Int, b: Int): Int =
        if (b == 0) a else gcd(b, a % b)
}

식별자 규칙

  • 영숫자 식별자 : 문자나 밑줄(_)로 시작. 문자, 숫자, 밑줄 가능
  • 필드, 메소드 인자, 지역 변수, 함수 등 : camelCase 사용이 관례
  • 클래스, 트레이트, 상수 등 : CamelCase 사용이 관례
  • 연산자 식별자 : 하나 이상의 연산자 문자로 이루어져 있음. + ++ ::: <?> :->
  • 혼합 식별자 : unary_+ myvar_=
  • 리터럴 식별자 : 역따옴표로 둘러싼 문자열

메소드 오버로드

class Rational(n: Int, d: Int) {
    require(d != 0)
    private val g = gcd(n.abs, d.abs)
    val numer: Int = n / g
    val denom: Int = d / g
    def this(n: Int) = this(n, 1)
    override def toString = n +"/"+ d
    def + (that: Rational): Rational =
        new Rational(
            numer * that.denom + that.numer * denom,
            denom * that.denom
        )
    def + (i: Int): Rational = // 덧셈 연산자 메소드 오버로드
        new Rational(numer + i * denom, denom)
    def - (that: Rational): Rational =
        new Rational(
            numer * that.denom - that.numer * denom,
            denom * that.denom
        )
    def - (i: Int): Rational = // 뺄셈 연산자 메소드 오버로드
        new Rational(numer - i * denom, denom)
    def * (that: Rational): Rational =
        new Rational(numer * that.numer, denom * that.denom)
    def * (i: Int): Rational = // 곱셈 연산자 메소드 오버로드
        new Rational(numer * i, denom)
    def / (that: Rational): Rational =
        new Rational(numer * that.denom, denom * that.numer)
    def / (i: Int): Rational = // 나눗셈 연산자 메소드 오버로드
        new Rational(numer, denom * i)
    private def gcd(a: Int, b: Int): Int =
        if (b == 0) a else gcd(b, a % b)
}

암시적 타입 변환

  • 암시적 타입 변환 메소드 지정 가능
  • 해당 스코프 내에 메소드가 존재해야 동작함
implicit def intToRational(x: Int) = new Rational(x)


+ Recent posts