Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コンストラクタ、知ってますよね?

okinari
January 23, 2019

 コンストラクタ、知ってますよね?

okinari

January 23, 2019
Tweet

More Decks by okinari

Other Decks in Technology

Transcript

  1. コンストラクタ
    知ってますよね?

    View full-size slide

  2. Self-introduction
    Name: okinari
    Twitter: @okinari
    Job: Web Engineer(Marketing Engineer)
    Interested: Dart / Flutter / Elixir / Node.js

    View full-size slide

  3. コンストラクタとは?
    オブジェクト指向のプログラミング言語で
    新たなオブジェクトを生成する際に呼び出されて
    内容の初期化などを行なう関数あるいはメソッドのことである。
    引用元:Wikipedia
    https://ja.wikipedia.org/wiki/コンストラクタ
    あんまり説明いらないですよね …

    View full-size slide

  4. こういうのを
    イメージしてますよね?
    ※スライド中のコードは
     動かないかもしれないので、
     ご注意ください。
    コンストラクタと言えば…
    class Hoge {
    String bar;
    Hoge(String foo) {
    this.bar = foo;
    }
    }

    View full-size slide

  5. これもコンストラクタ
    class Point {
    num x, y, o;
    Point(this.x, this.y);
    Point.onlineX(this.x): this.y = 0 {
    print('On the X line.');
    }
    Point.onlineY(this.y): this.x = 0 {
    print('On the Y line.');
    }
    Point.origin(): this(0, 0);
    }

    View full-size slide

  6. “もう笑うしかないよ

    View full-size slide

  7. コンストラクタの種類
    (多すぎるよ…)
    ・Default constructors
    ・Named constructors
    ・Redirecting constructors
    ・Constant constructors
    ・Factory constructors
    ・Initializer list(※)
    ※コンストラクタの種類ではない
    引用元:公式のLanguage Tourより
    https://www.dartlang.org/guides/language/language-tour#constructors

    View full-size slide

  8. ・標準コンストラクタ
    ・要は普通のやつ
    Default constructors
    class Point {
    num x, y;
    Point(num x, num y) {
    this.x = x;
    this.y = y;
    }
    }

    View full-size slide

  9. class Point {
    int x, y;
    Point(this.x, this.y);
    Point.n(this.x, this.y, int n) {
    print(n);
    }
    }
    Default constructors
    ・コンストラクタに限り、
     引数でインスタンス変数を
     変更可能
    ・追加の引数はもちろんOK
    ・内部で処理を書くのもOK

    View full-size slide

  10. ・名前付きのコンストラクタ
    ・C++とかにはあるらしい?
    - 僕は初めて知りました
    ・呼び出し時、staticメソッド
     との見分けがつかない
    Named constructors
    class Point {
    num x, y;
    Point(this.x, this.y);
    Point.origin() {
    x = 0;
    y = 0;
    }
    }

    View full-size slide

  11. Named constructors
    class Point {
    num x, y;
    Point();
    Point.pConstructor() {
    this.x = 0;
    this.y = 0;
    }
    static Point pMethod() {
    Point point = new Point();
    point.x = 0;
    point.y = 0;
    return point;
    }
    }
    void main() {
    // コンストラクタ
    Point.pConstructor();
    // staticメソッド
    Point.pMethod();
    }
    // どちらもPointオブジェクトが
    // 取得できる

    View full-size slide

  12. ・別のコンストラクタへ
     リダイレクト
    ・リダイレクトなので、
     追加の処理はできない
    ・別のコンストラクタと、
     共通の処理がある場合は、
     メソッドを使う必要がある
    Redirecting constructors
    class Point {
    num x, y;
    Point(this.x, this.y);
    Point.alongXAxis(num x)
    : this(x, 0);
    }

    View full-size slide

  13. ・定数コストラクタ
    ・final以外のフィールドは
     定義不可
    Constant constructors
    class Point {
    static final Point origin =
    const Point(0, 0);
    final num x, y;
    const Point(this.x, this.y);
    }

    View full-size slide

  14. ・ファクトリーコンストラクタ
    ・常に新しくインスタンスを
     作成するとは限らない場合、
     factoryを使うべし?
     - ファクトリーパターン?
     - シングルトンパターン?
    ・Loggerなど…(例が思いつかん)
    シングルトンパターンと
    ファクトリーパターンの違いに混乱 …
    Factory constructors
    class Logger {
    final String name;
    static final Map _cache =
    {};
    Logger._internal(this.name);
    factory Logger(String name) {
    if (_cache.containsKey(name)) {
    return _cache[name];
    } else {
    final logger =
    Logger._internal(name);
    _cache[name] = logger;
    return logger;
    }
    }
    }

    View full-size slide

  15. Factory constructors
    factory Logger(String name) {
    if (_cache.containsKey(name)) {
    return _cache[name];
    } else {
    final logger = Logger._internal(name);
    _cache[name] = logger;
    return logger;
    }
    }

    View full-size slide

  16. Factory constructors
    static Logger getInstance(String name) {
    if (_cache.containsKey(name)) {
    return _cache[name];
    } else {
    final logger = Logger._internal(name);
    _cache[name] = logger;
    return logger;
    }
    }

    View full-size slide

  17. ・staticメソッドで
     同じように書けるような…?
    ・コンストラクタとの違いは
     (たぶん)呼び出し方だけ
    ・staticメソッドの場合、
     メソッド名が必須なので、
     名無しで表現するには、
     factoryコンストラクタが必須
     - 通常のコンストラクタ風
    Factory constructors
    void main() {
    Logger loggerFactory =
    Logger('name');
    Logger loggerStaticMethod =
    Logger.getInstance('name');
    }

    View full-size slide

  18. Initializer list
    ・初期化リスト?
    ・変数を初期化する
    ・右辺に同じクラスの
     メソッドを使う場合、
     staticメソッドのみ使用可 
    ・finalフィールドを宣言時と
     コンストラクタ引数以外で
     初期化できる方法
    class Point {
    int x, y;
    Point(Map json)
    : this.x = json['x'],
    this.y = json['y'] {
    print('call Point($x, $y);');
    }
    }

    View full-size slide

  19. まとめ(感想)
    ・コンストラクタの書き方はたくさんあるから
     注意しよう!
    ・(Flutterの場合)オブジェクト生成にて画面を
     構築するので、その簡易化が目的(かも?)
    ・それにしても多すぎない…?

    View full-size slide

  20. Thanks!
    ご質問などあれば、
    下記までお願いします。
    @okinari (Twitter)

    View full-size slide