기본 콘텐츠로 건너뛰기

6월, 2015의 게시물 표시

chap 12 고차함수 (high-order-function)

고차함수   - 함수를 인자로 받거나, 리턴해주는 함수 1. 값으로서 함수   - 함수를 변수에 저장할수 있다. scala> val fun = ceil _ fun: Double => Double = < function1 > ceil은 임의수보다 크거나 같은 수 가장 작은 수를 리턴해주는 함수이다. 기술적으로 _는 ceil 메소드를 함수로 바꾼다. 스칼라에서 메소드는 조작할 수 없고, 오직 함수만 가능. 2. 익명함수 scala> Array ( 3.14 , 1.42 , 2.0 ).map((x: Double )=> 3 *x) res5: Array [ Double ] = Array ( 9.42 , 4.26 , 6.0 ) 익명클래스도 그렇고, 이제는 익명이 조금 익숙해지기 시작한다. 함수의 실행순서가 중요해보인다. 3. 함수인자를 받는함수 scala> def mulBy (factor : Double ) = (x : Double ) => factor * x mulBy: (factor: Double ) Double => Double scala> val quintuple = mulBy( 5 ) quintuple: Double => Double = < function1 > scala> quintuple( 20 ) res7: Double = 100.0 quintuple 은 mulBy(5) 즉, (x:Double) => 5 * x 를 리턴한다. mulBy는 어떤 값을 곱하는 함수를 생성한다. 팩토리 같기도하고 클래스 같기도하고..  ㅎ 4. 인자추론 scala> def valueAtOneQuarter (f:( Double ) => Double ) = f( 0.25 ) valueAtOneQuarter: (f: Double => Double ) Double scala> valueAtOneQuarter

chap 10. trait

trait. 일단 java의 interface 같은 놈인듯 한데, 뭔가 다른게 있는것 같다. 1. 다중상속의 문제 아래의 Student, Employee개의 부모클래스가 있고, 이둘을 상속하는 TeachingAssistant 라는 클래스가 있다. class Student { def id : String = ... } class Employee { def id : String = ... } class TeachingAssistant extends Studet, Employee { .. } 그런데 문제는 두개의 부모클래스가 id라는 공통되는 변수를 가진다면 상속받는 클래스에서는 어떤 id를 택하게 될까라는 고민거리가 생긴다. 또 다이아몬드상속문제(Student와 Employee 역시 Person이라는 클래스를 상속한 서브클래스였다면)가 발생했을시 어떻게 할까, C++에서는 '가상 베이스 클래스' 라는 기능을 사용하고, 자바에서는 다중상속을 지원하지 않고, 인터페이스는 추상 메소드만 가질수 있고 필드는 가질 수 없게 한정하였다. scala에서는 이러한 다중상속문제 다루기위해 trait을 사용한다. 2. trait가 있는 오브젝트 trait는 자바의 인터페이스 기능을 수행한다. 인터페이스처럼 함수 구현부는 없이 사용할 수도 있지만, trait Logger { def log (msg: String ) } 인터페이스와는 달리 일반클래스처럼 함수를 구현해놓을 수도 있다. trait ConsoleLogger  extends Logged { def log (msg: String ){println(msg)} } 그리고 후자의 경우는 trait이 클래스의 믹스인 되었다 라는 표현을 사용한다. 그리고 믹스인이 된 클래스들은 trait이 변경되면 믹스인한 모든 클래스가 재 컴파일 되야하니 알고쓰자. 오브젝트를 생성할때 trait를 추가할 수 있다. trait Logged

scala 8. 상속

1. extends 상속은 자바와 마찬가지로 extends 라는 키워드를 사용 class Person { var name = "" override def toString = getClass().getName + "[name=" + name + "]" } ... class Employee extends Person{ var salary = 0.0 override def toString = super .toString + "[salary=" + salary + "]" } 상속을 막고 싶으면 final을 사용 2. override 오버라이드(함수를 상속받아 재정의, cf 오버로드-함수의 파라미터 갯수를 달리하여 재정의)를 할경우 추상메소드인경우에는 그냥 진행하면 되지만, 그렇지 않은경우 메소드 앞에 override를 붙여준다. class Person { var name = "" override def toString = getClass().getName + "[name=" + name + "]" } ... class Employee extends Person{ var salary = 0.0 override def toString = super .toString + "[salary=" + salary + "]" } 실행 object test { def main (args: Array [ String ]): Unit ={ var ch = new Employee println(ch.toString) } } < result > [name=][salary= 0.0 ] 3. 슈퍼클래스 생성자 - java에서 부모클래스의 생

scala 6. object

오브젝트 보통 클래스로부터 생성한 객체를 오브젝트라 칭한다. scala서 오브젝트는 위의 개념이 아니다. 1. 싱글톤  object로 생성되는건 싱글톤이다. 싱글톤 객체로 사용하고 싶을때 object를 사용한다 2. 컴패니언오브젝트( http://www.scala-lang.org/api/2.11.6/#scala.annotation.meta.companionObject )  컴패니언뜻은 동료, 동반자, 친구 뭐 이런뜻이다.  발번역하면 클래스와 친구인 오브젝트.. 뭐 이런건가 ㅋ  오브젝트는 위에서 말한것처럼 정적인 객체다, 정적인 필드와 메소드를 가지고 있다.  클래스에서 일부 정적인 기능이 필요한 경우 사용하라고 만들었다. class Account { val id = Account .newUniqueNumber() private var balance = 0.0 def deposit (amount : Double ): Unit ={ balance += amount } } object Account { private var lastNumber = 0 private def n zjaewUniqueNumber()={ lastNumber += 1 lastNumber } } Account컴패니언 오브젝트를 생성했다. Account의 인스턴스가 생성되면 고유한 ID값을 부여할 수 있다. scala> var ac1 = new Account ac1: Account = Account @35ff8fc9 scala> var ac2 = new Account ac2: Account = Account @29c2c826 scala> ac1 res10: Account = Account @35ff8fc9 scala> ac1.id res11: Int = 1 scala> ac2.id res12: Int = 2 3. 클래스나

scala 5. class

1. 클래스 scala> class Counter { | private var value = 0 | def increment () { value += 1 } | def current () = value | } defined class Counter 앞에서 했던 내용들하고 비교해보면 특별한건 없어보인다. 단 파라미터가 없는 메소드의 경우 가급적 '( )' 없이 사용하길 권장한다고 한다. 2. 게터와 세터 자동생성 scala> class Person { var age = 0 } defined class Person scala> val chang = new Person chang: Person = Person @157fe3d class 내부에 age라는 변수만 초기화 해놨다. 별다른 표시가 없으면 멤버 접근권한은 기본적으로 public으로 존재한다. scala> chang.age res9: Int = 0 scala> chang.age = 1 chang.age: Int = 1 scala> chang.age res10: Int = 1 이부분이 조금 매력적이다. 사용할때는 .age 하나인데, 이걸로 setter도 되고 getter의 기능도한다. scala에서는 만약 멤버변수 int타입 age가 생성되면 getter는 int age() = age setter는 void age_=(int) 의 형식으로 자동으로 내부적으로 생성한다. 그리고 멤버 변수가 var가 아닌 val으로 선언했다면 그 멤버의 setter는 생성되지 않는다. 또한 getter와 setter는 자동으로 생성은 됬지만, 입맛에 맞게 수정하여 사용할 수 도 있다. 3. 비공개필드 클래스에서 일부 필드를 비공개로 숨기는 기능이 있다. 대게 private한 변수들도 메소드내에서는 접근이 가능하다. 그런데 여기서는