Essential ActionScript 3.0 読書メモ 第27回 Get/Setメソッド

一つ前の回で、取得(retriever)・変更(modifier)メソッドについて学んだ。取得・変更メソッドは、publicメソッドで、オブジェクトの状態を取得したり変更したりする。

より簡便な取得・変更の方法として、ActionScriptはget/setメソッドをサポートしている。これらのメソッドは、変数の取得や代入の書き方で利用できる。

get/setメソッドを定義するには、次のように書く。

function get/set methodName() {
  statements
}

setメソッドについて注意すべき点は、returnを書いてはいけないという点である。setメソッドには、自動で設定される戻り値があるからである。

get/setメソッドを呼ぶ際には、独特の書き方がある。メソッドの後ろの括弧は必要ない。

例:
class Blog {
  private var title;

  public function get title () {
    return title;
  }

  public function set title (newTitle) {
    if (newTitle > 100) {
      newTitle = newTitle.substr(0, 100);
    } elseif (newTitle == “”) {
      return;
    }
    this.title = newTitle;
  }
}

var blogTitle = Blog.title; // get
Blog.title = “web engineer”; // set

取得・変更メソッドと、get/setメソッドのいずれを選ぶかは、好みの問題である。

今日の進捗:356→366/3546(ページ数のカウント方式を変更)

Essential ActionScript 3.0 読書メモ 第26回 メソッドでオブジェクトの状態を調べ、変更する

インスタンス変数をprivateで宣言し、そのインスタンス変数が定義されたクラスの外側のコードから読んだり変更させたりしないようにしておくのが、良いオブジェクト指向プログラミングのやり方である、というのは既に学んだ通り。

良いオブジェクト指向プログラミングのやり方では、外部のコードにインスタンス変数を直接変更させる代わりに、オブジェクトの状態を調べたり変更したりするインスタンスメソッドを定義すべきとされている。

どこからでもインスタンス変数の値が変更できるなら、ある値が本当に有効な値を持っているのかの確証がなくなってしまう。Blogクラスのインスタンス変数titleを取り出してみたら、中身はブログタイトルではなく記事のタイトルでした、なんてことでは困る。

このような問題を避けるために、インスタンス変数はprivateで宣言すべきである。外部のコードにインスタンス変数へのアクセスを許可する代わりに、publicなインスタンスメソッドを用意し、それぞれのオブジェクトの状態を安定した方法で変更できるようにする。
例:

class Blog {
  private var title;

  public function getTitle () {
    return this.title;
  }

  public function setTitle (newTitle) {

    if (newTitle > 100) {// titleが100文字以上ある場合
      newTitle = newTitle.substr(0, 100); // 100文字目までを取り出す(101文字目以降は除去)

    } else if (newTitle == “”) {// 新しいタイトルとして与えられた文字列が空の場合
      return;// this.titleには変更を加えず、メソッドを終了
    }
    this.title = newTitle;
  }
}

伝統的なオブジェクト指向プログラミングの用語では、オブジェクトの状態を取得するメソッドをアクセッサー(accessor)あるいはゲッター(getter)、変更するメソッドをミューテーター(mutator)あるいはセッター(setter)と呼ぶ。しかし、ActionScript 3.0では、「アクセッサーメソッド」という用語は特別のメソッドを意味する。そのため、Essential ActionScript 3では、これらの用語を使用していない。代わりに、取得メソッド(retriever method)/変更メソッド(modifier method)という用語を使用している。

今日の進捗:428→449/4343 全体の1割が終了!

Essential ActionScript 3.0 読書メモ 第25回 バインドメソッド

ActionScriotでは、メソッドはそれ自身値として扱える。すなわち、メソッドは変数に代入したり、関数や他のメソッドに渡したり、他の関数やメソッドから返したりできる。

class Blog {
  var private title;
  public function setTitle(title) {
    this.title = title;
  }
}

というメソッドがあったとして、このメソッドを変数に代入するには、

blog = new Blog();
var set = blog.setTitle;

と書く(メソッド名の後ろに括弧はつけない点に注意)。また、変数setからメソッドsetTitle()を呼ぶには、

set(“web engineer blog”);

のように書く。このコードが実行されると、blogオブジェクトのインスタンス変数titleの値が”web engineer blog”になる。つまり、変数setはblogオブジェクトのsetTitle()メソッドを参照している。

変数に代入されたり、関数又はメソッドに渡されたり、関数又はメソッドの返り値になったりするメソッドのことを、バインドメソッドという(「バインドメソッド」はbound methodの日本語訳として定着している。なおboundはbindの過去分詞)。

今日の進捗:420→428/4343

Essential ActionScript 3.0 読書メモ 第24回 変数名の衝突を防ぐ

インスタンス変数とメソッドパラメーターが同じ名前をもっているとき、thisキーワードを使うことでそれぞれを区別して変数にアクセスすることができる。
例:

internal class Blog {
  private var title = “title1”;
  public function setTitle (title) {
    this.title = title;
  }
}

上の例では、インスタンス変数のtitleがパラメーターのtitleと同じ名前になっている(インスタンス変数titleに、setTitle()の引数として与えられた値を代入)。そのため、(名前解決において優先度の高い)パラメーターのtitleが、(優先度の低い)インスタンス変数のtitleを隠蔽し、thisキーワード無しではインスタンス変数titleにアクセスできなくしている。同様に、ローカル変数もインスタンス変数とインスタンスメソッドを隠蔽する。

インスタンス変数、インスタンスメソッドとパラメーター、ローカル変数に同じ名前をつけるプログラマーも多いが、名前の衝突を避けるためには、同じ名前をつけない方が良い。

今日の進捗:415→420/4343

Essential ActionScript 3.0 読書メモ 第23回 thisの省略と名前解決

今日からChapter 3「Instance Methods Revisited」。

thisキーワードが、コンストラクターメソッド及びインスタンスメソッドにおいて、カレントオブジェクト(current object、現在進行形で作成・実行されているオブジェクト)を指し示すのに使われることは、すでに学んだとおり。
例:

public function Blog (words) {
    this.title = words;
}

しかし、カレントオブジェクトに頻繁にアクセスするコードの中で、いちいちthisを書くのはわずわらしいし、可読性を下げる。ActionScriptでは、カレントオブジェクトのインスタンス変数とインスタンスメソッドにアクセスする際に、thisを省略することができる。

コンストラクターメソッド又はインスタンスメソッドの中で、ActionScriptが式の中の識別子に遭遇すると、ActionScriptはローカル変数、パラメーター、ネストされた関数を探索する。これらの中に、識別子に該当するものが存在しない場合、ActionScriptはインスタンス変数又はインスタンスメソッドから名前の一致するものがないか探索する。もし見つかれば、そのインスタンス変数又はインスタンスメソッドが、式の変数として使われる。

例:
class Pet {
  var currentCalories; // インスタンス変数
  public function eat (numberOfCalories) {
    currentCalories += numberOfCalories;
    // 上の式は、 this.currentCalories += numberOfCalories; と等価
  }
}

eat()メソッドが実行されると、ActionScriptはまず、numberOfCaloriesという識別子に遭遇する。そして、ローカル変数、パラメーター、ネストされた関数から一致する名前のものを探す。ここでは、numberOfCaloriesというパラメーターがメソッドに対して与えられているから、メソッドの本文中のnumberOfCaloriesとは、パラメーターとして与えられたnumberOfCaloriesのことだ、と解釈する。

次に、currentCaloriesという識別子に遭遇する。ローカル変数、パラメーター、ネストされた関数から一致する名前のものを探すが、見つからない。そこで、ActionScriptは、インスタンス変数とインスタンスメソッドから同名のものを探索する。すると、currentCaloriesというインスタンス変数が見つかるので、ActionScritptはそのインスタンス変数をeat()メソッド内のcurrentCaloriesとして用いる。

このように、プログラムの処理系が識別子の名前をもとにして変数や関数を探索することを、「名前解決(identifier resolution)」と呼ぶ。

今日の進捗:402→415/4343