LoginSignup
0

More than 5 years have passed since last update.

がばがばscala独学-クラス(1)

Last updated at Posted at 2017-07-19

はじめに

下記のテキストを通して、基本的な書き方を学びつつ、個人的に気になったことを検証していくメモ代わりです。
https://dwango.github.io/scala_text/basic.html
本当にありがとう、dwango様・・・

クラス

大学の講義程度のJavaをやっていたので前提知識は大丈夫だと思いたい

最低限、Javaのクラスがわかっている事を前提にします

ざっくりまとめ

  • classはclass ClassName で定義し、内部にはfield or methodを定義可能で、引数に対してval/varで外部読み出し可能な変数を宣言可能
  • methodは def methodName で定義可能
  • field定義は次回に持越し

クラス定義

  • 一般型

    class ClassName(parameter1: Type1, parameter2: Type2, ...) {
      (a field or method definition)の0回以上の繰り返し
    }
    
  • 点を表すクラスPointを定義

    • 基本的な定義

      scala> class Point(_x: Int, _y: Int) {
           |   val x = _x
           |   val y = _y
           | }
      defined class Point
      
      scala> Point(10, 20)
      <console>:8: error: not found: value Point
                    Point(10, 20)
                    ^
      
      scala> new Point(10, 20)
      res1: Point = Point@1605dc19
      
      • class定義をする方法をすっかり忘れていた・・・
    • 定義と公開を両方成す場合

      scala> class Point(val x: Int, val y: Int)
      defined class Point
      
      scala> new Point(10, 20)
      res0: Point = Point@513ed3da
      
      • コンストラクタの引数をそのまま公開したい場合、一行でOK
    • 外部公開をした場合の処理

      scala> class Point(val x: Int, val y: Int) {
           |   def +(p: Point): Point = {
           |     new Point(x + p.x, y + p.y)
           |   }
           |   override def toString(): String = "(" + x + ", " + y + ")"
           | }
      defined class Point
      
      scala> val p = new Point(10, 20)
      p: Point = (10, 20)
      
      scala> println(p.x)
      10
      
      scala> println(p.y)
      20
      
      scala> println(p.toString)
      (10, 20)
      
      
      • 複数のコンストラクタが定義できるので、この最初の1つのコンストラクタをプライマリコンストラクタとして特別に扱う
      • プライマリコンストラクタの引数にval/varをつけるとそのフィールドは公開され、外部からアクセスできるようになります
      • + ってなんだ? → メソッド定義へ

メソッド定義

  • 一般型

    (private[this/package名]/protected[package名]) def methodName(parameter1: Type1, parameter2: Type2, ...): ReturnType = {
      ???
    }
    
  • メソッド本体が1つの式だけからなる場合

    (private[this/package名]/protected[package名]) def methodName(parameter1: Type1, parameter2: Type2, ...): ReturnType = ???
    
  • 実際に使ってみる

    scala> class Point(val x: Int, val y: Int) {
         |   def +(p: Point): Point = {
         |     new Point(x + p.x, y + p.y)
         |   }
         |   override def toString(): String = "(" + x + ", " + y + ")"
         | }
    defined class Point
    
    scala> val p1 = new Point(1, 2)
    p1: Point = (1, 2)
    
    scala> val p2 = new Point(4, 8)
    p2: Point = (4, 8)
    
    scala> println(p1.x.toString + " " + p1.y.toString)
    1 2
    
    scala> println(p2.x.toString + " " + p2.y.toString)
    4 8
    
    scala> val p3 = p1 + p2
    p3: Point = (5, 10)
    
    • val p3 = p1 + p2 を使用するための + だったのか
  • 一応確かめで + を定義しなかった場合の処理

    scala> class Point(val x: Int, val y: Int) {
         |   override def toString(): String = "(" + x + ", " + y + ")"
         | }
    defined class Point
    
    scala> val p1 = new Point(1, 2)
    p1: Point = (1, 2)
    
    scala> val p2 = new Point(4, 8)
    p2: Point = (4, 8)
    
    scala> val p3 = p1 + p2
    <console>:10: error: type mismatch;
     found   : Point
     required: String
           val p3 = p1 + p2
    

複数の引数リストを持つメソッド

  • 一般型

    def methodName(parameter11: Type11, parameter12: Type12, ...)(...)(parameterN1: TypeN1, ..., parameterNM: TypeNM): RerurnType = ???
    
  • 使い方

    scala> class Adder { def add(x: Int)(y: Int): Int =  x + y  }
    defined class Adder
    
    scala> val adder = new Adder()
    adder: Adder = Adder@3acc82b0
    
    scala> val result = adder.add(1)(2)
    result: Int = 3
    
    scala> val func = adder.add(10)_
    func: Int => Int = <function1>
    
    scala> func(20)
    res11: Int = 30
    
    • val func = adder.add(10)_ 最初の引数だけを適用して新しい関数を作る(部分適用)こともできる
    • 部分適用で共通処理の簡略化ができそう

フィールド定義

  • 一般型

    (private[this/package名]/protected[package名]) (val/var) fieldName: Type = Expression
    
    • private / protected 関連
      • private :そのクラス内のみでアクセス可能
      • protected :そのクラスの派生クラスからのみアクセス可能
      • private[this] :同一オブジェクトからのみアクセス可能
        • 一般にJVMレベルでのフィールドへの直接アクセスになるため、若干高速
      • private/protected[package名]:同一パッケージからの各定義でのアクセス可能

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0