92.86%

1時間32分

解決済 最近のプログラミング言語にgetter/setterがないのはなぜ?

  • Java

    3359questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android

    1709questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Swift

    1071questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • iOS

    944questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • プログラミング言語

    257questions

    プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

2016/02/20 19:16 投稿

TetsuroMikami score 11

  • 5

    回答

  • 7

    評価

  • 1588

    view

プログラミング2年目で、Androidのアプリ開発から始め、Swiftで最近iOSもちょっとやってます。
SwiftやKotlinに若干触れた際の疑問です。

Javaでは、一般に、フィールド変数を直接参照するよりも、getter/setterメソッドを介して値をgetなりsetなりするのが良い、と最初の頃に読んだ本に書いてあり、実際それに沿った実装が多いと思います。

一方、SwiftやKotlinでは、フィールド変数はメソッド経由ではなく、直接参照したり、変更したりするような言語の設計になっていると理解しています。

そこで質問なのですが、なぜこれらの比較的新しい言語では、getter/setterを嫌って(?)このような設計となっているのでしょうか?
これによるメリットって、getter/setterを毎回書かなくて済むっていうことだと思うのですが、AndroidStudioだったら自動で書いてくれる機能がありますし、他のIDEでも、プラグインなどで同じ機能は簡単に実現できると思います。

むしろ、デメリットとして、次のような点があると思っています。

・参照したい時にとりあえずgetって打ってから予測変換で探すことができないからめんどい
・Swiftだと、ある変数の値を変えようとして代入すると、"この変数はReadOnlyだよ"とかいった警告が出てきて、だるい(それならgetterだけ実装してsetterを実装しなければいいのに)

そしてこのデメリットはメリットと比べて大きすぎるように自分は思うのですが、getter/setter排除による、僕が気づいていないメリットが他にあるのでしょうか?

情報の追加・修正の依頼をする(0)

※回答は回答欄にご記入下さい。

記入例

  • ・質問の「○○○」の部分をもう少し具体的に書いてください。
  • ・開発環境は何ですか?(OSやバージョン)
  • ・「○○○」の部分に誤字脱字があります。

気になる質問をクリップする

クリップした質問に回答があった場合に通知・メールを受け取ることができます。

クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。

良い質問の評価を上げる

以下のような質問は評価を上げましょう。

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

質問の評価を上げたことを取り消します

7

質問の評価を下げる

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 広告と受け取られるような投稿

評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

評価を下げる理由を選択してください

上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

質問の評価を下げる機能の利用条件

この機能を利用するためには、以下の事項を行う必要があります。

質問の評価を下げたことを取り消します

回答(全5件)

ベストアンサー

回答の評価を上げる

以下のような回答は評価を上げましょう。

  • 正しい回答
  • わかりやすい回答
  • ためになる回答

評価が高い回答ほどページの上位に表示されます。

15

回答の評価を下げる

以下のような回答は評価を下げられます。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • 不快な投稿

評価を下げる際は理由をコメントしてください。

なぜこれらの比較的新しい言語では、getter/setterを嫌って(?)このような設計となっているのでしょうか? 
getter/setter排除による、僕が気づいていないメリットが他にあるのでしょうか?

最大のメリットは、コードが簡潔になることだと思います。Java的なgetter/setter方式では冗長な記述が増えるため、プログラマにそのようなBoilerplateコードを書かせないための言語設計です。

一方、SwiftやKotlinでは、フィールド変数はメソッド経由ではなく、直接参照したり、変更したりするような言語の設計になっていると理解しています。 

上記解釈は、適切でないと思います。Kotlinには プロパティ(property) という仕組みがあり、これは改良されたgetter/setterと解釈できます。Swiftも同じく プロパティ という機能を持っています。

知っている限り、Java言語以降に登場したプログラミング言語ではgetter/setter方式よりも、property方式のほうが主流だと思います。

・Swiftだと、ある変数の値を変えようとして代入すると、"この変数はReadOnlyだよ"とかいった警告が出てきて、だるい(それならgetterだけ実装してsetterを実装しなければいいのに) 

値の取得のみを許す/設定は許可しないという設計に対して、誤ったコードにコンパイラが警告を出しているので、getterのみが提供される状態と同義です。(単に"慣れ"の問題と捉えました。)

・参照したい時にとりあえずgetって打ってから予測変換で探すことができないからめんどい

これについては、たしかに一定のメリットがあります。ただし、そもそもフィールドと1:1対応させたgetterを持たせることが、オブジェクト指向設計として適切なのかという議論が昔からあります。

古くは2003年頃の"Why getter and setter methods are evil"まで遡れるようです。他にも"getter setter"で検索すると様々な意見があるかと思います。本回答では断定的な表現はさけますが、全体の論調としては反対派が優勢ですし、現にモダンな言語ではgetter/setterを避ける機構が用意されています。

2016/02/20 19:59 投稿

2016/02/20 20:01 編集

yohhoy score 752

コメント(6)

2016/02/20 20:08

> そもそもフィールドと1:1対応させたgetterを持たせることが、オブジェクト指向設計として適切なのかという議論が昔からあります。

ほんと、実はこれがポイントのように思います。たくさんのgetter/setterを定義するクラスって少ないですもんね。

2016/02/20 20:17

回答ありがとうございます。
どうもSwiftやKotlinについての僕の理解が足りていないようですね。
勉強します。

2016/02/20 20:30

Javaであってもsetterはあまり定義しないほうが楽ですね。
setterがあると、「この不正状態を作った奴は誰だぁ!」をしないといけないので。

2016/02/21 11:18

yohhoyさんのお答えの通りかと思いますが、歴史的経緯としては「Javaのgetter/setter方式がよろしくないからプロパティ方式が広まった」というよりは、「プロパティ方式を取り込もうとしたJava陣営が、文法ルール拡張を避けるためにgetter/setterのメソッド名ルールという規約でプロパティを表現することにした」の方がより実体に近いと思います。

2016/02/22 12:33 編集

Javaのgetter/setterはJavaBeans仕様が初出(という説が有力)なので、1996~1997年頃から歴史があるようですね。JavaBeansはフレームワークの規約ですから、言語本体の仕様拡張を嫌ったという側面が強いと思います。

プロパティ構文を導入した他プログラミング言語については、それより早い・遅いを調べるのは難しいですね…。軽く調べた感じだとD言語が2001年、C# v1.0が2002年、Objective-C 2.0が2006年ですから、いずれもJavaBeansよりは後発の様です。

2016/02/23 14:33 編集

プロパティは現代のRAD的なGUI設計スタイルに起点があると思います。
RADスタイルでGUIを設計するのはVisual Basicが最初ではないかと思います。VBの初版は1991年みたいです。
それがDelphiに取り込まれ、C++Builderへ展開され、その開発メンバの一部がマイクロソフトに引きぬかれてC#へ引き継がれたと理解してます。

ただ、RADの3大要素のプロパティ、メソッド、イベントの内どれか一つはVBにはなかった記憶が有ります。どれだったのかもう記憶に残ってません。
でも、1995年のDelphiでは3つ揃っていました。私はDelphi 1.0を展開したC++Builder 1.0にて初めてプロバティを扱って感動した記憶があります。

【追記】
探したら、VB 2.0の情報がありました。
http://www.ipentec.com/document/document.aspx?page=software-visual-basic-20-install
プロパティ・ウィンドウにはC++Builderもよく似た項目が並んでました。VB 6.0とC++Builderのプロパティは同じ働きでした。VB 2.0を触ったことはないですが議論の対象になっているプロパティと同じと思いますよ。VB 2.0は1992年のようです。

回答の評価を上げる

以下のような回答は評価を上げましょう。

  • 正しい回答
  • わかりやすい回答
  • ためになる回答

評価が高い回答ほどページの上位に表示されます。

5

回答の評価を下げる

以下のような回答は評価を下げられます。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • 不快な投稿

評価を下げる際は理由をコメントしてください。

まず現状として Java が getter や setter に言語レベルで対応していないのでわざわざメソッドを作らなければならなくなっています。
Swift はプロパティーに対して didSet や willSet を設定できるためそもそもメソッドを作る必要がありません。読み取り専用プロパティーは getter だけ実装すれば良いというのはその通りで、Swift でもそのようにプロパティーを定義することで readonly になります。
わたしは C# という自動実装プロパティーという機構を持つ言語(Swift に似ています)を使っていますが get と打ってプロパティの一覧を得るようなことはしませんし、むしろ短く表記できるのでこの方が便利だと感じます。慣れの問題ではないでしょうか…。

2016/02/20 19:51 投稿

chitoku score 270

コメント(2)

2016/02/20 20:08

SwiftのdidSetなどは知りませんでした。教科書的な記述をすっ飛ばして実装してしまっていたので、きちんと勉強しなければと思いました。
ご指摘ありがとうございます。

プロパティの一覧を補完機能から得るというのが、褒められたやり方でないというのは承知していますが、皆さんプロパティ名をど忘れたりとかってないのでしょうか?笑

2016/02/20 20:15

もちろんプロパティーに対して補完機能は使いますが、別に get で始まっていなくても補完されますよね…?

回答の評価を上げる

以下のような回答は評価を上げましょう。

  • 正しい回答
  • わかりやすい回答
  • ためになる回答

評価が高い回答ほどページの上位に表示されます。

5

回答の評価を下げる

以下のような回答は評価を下げられます。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • 不快な投稿

評価を下げる際は理由をコメントしてください。

こんにちは。

「getter/setterが無い」のではなく、「プロパティがある」のではないでしょうか?
フィールドに対して参照/設定をするのと同じ構文で、getter/setterを呼び出せる機能がプロパティと呼ばれています。そのような言語でもgetter/setterを定義することは可能な筈です。
ですので、他のプロジェクト・メンバーと話して合意が得られれば、プロパティを使わないで旧来のgetter/setterを使えばよいのではないでしょうか?

getter/setterをいちいち定義しなくて済むことが嬉しい人はプロパティを使えば良いし、予測変換でメソッドが出てこないことが嬉しいし人はgetter/setterを定義すれば良いように思います。
両方取りたい人は命名規則を決めて、メソッド、リードライト可能なメンバ変数、リードオンリなメンバ変数のプリフィックスを被らないように定めることも可能かと。

2016/02/20 20:04 投稿

Chironian score 2682

回答の評価を上げる

以下のような回答は評価を上げましょう。

  • 正しい回答
  • わかりやすい回答
  • ためになる回答

評価が高い回答ほどページの上位に表示されます。

0

回答の評価を下げる

以下のような回答は評価を下げられます。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • 不快な投稿

評価を下げる際は理由をコメントしてください。

無意味な回答ですので削除します(回答の削除方法がわからない・・・)

2016/02/23 13:02 投稿

2016/02/23 13:08 編集

k_yosi score 6

回答の評価を上げる

以下のような回答は評価を上げましょう。

  • 正しい回答
  • わかりやすい回答
  • ためになる回答

評価が高い回答ほどページの上位に表示されます。

0

回答の評価を下げる

以下のような回答は評価を下げられます。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • 不快な投稿

評価を下げる際は理由をコメントしてください。

実用面でのお話については、殆どの理由が挙がっているので、オブジェクト指向としての考え方に則した面での論点をば。

「オブジェクトは、単なるデータホルダーではない」
が尤もな理由のように感じます。

http://tbd.kaitoy.xyz/2015/07/22/getters-setters-evil/

Javaには、他の言語いうプロパティ相当の昨日はありませんが、メソッドで代用するにしても、すべてにおいてset〜とか、get〜とするのはよくないと思います。
あとは、Javaでありがちなbooleanを返すis〜というメソッド。
wasでもhaveでもneedでも、その時々の最適な命名が存在するはずです。
不変オブジェクトであれば、getterメソッドも不要で、そのままpublic finalなフィールドへアクセスさせてもいいと思います。(モジュール結合強度上がってしまうし、Mock化してテストし辛いので、実用面では避けたほうがいいですが)

2016/02/23 13:14 投稿

poad1010 score 9

関連した質問

同じタグがついた質問を見る

  • Java

    3359questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android

    1709questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Swift

    1071questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • iOS

    944questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • プログラミング言語

    257questions

    プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

関連した質問

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る