• ベストアンサー

メンバ変数をpublicにするかset/getメソッドを定義するか

Smarty入門という本を読んでいると、 class foo {  private $_a;  public function get_a() { return $this->_a;}  public function set_a(a) { $this->_a=a; }  : } というコーディングがありました。 class foo {  public $a;  : } というほうが素直だと思うのですが、上のように書く理由は何かあるのでしょうか? 書籍には、直接アクセスするのは望ましくなく、メソッド経由で行うべきと書いてありましたが、get/setの両方共を定義するならpublicと同じだと思います。 何らかの事情で変数名を変えた場合も、同じ事情でアクセスメソッド名も変えるべきだと思うので、メンテナンス性も同じだと思います。「変数名は絶対変えるべきだがアクセスメソッド名は別に変えなくて良い」というへんてこな事情が発生すれば別ですが。

  • notnot
  • お礼率77% (192/248)
  • PHP
  • 回答数2
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

get/setメソッドを定義し、値を制御する事で予期せぬ値を入れられる心配などもなくなります。 (例えば数値を入れる変数に文字は入らないよう制御できる) getだけであれば、取得のみが可能なプロパティだったり、という事も出来ます。 基本的に第三者が、そのプログラムを利用して プログラムを記述する場合には利用した方が良いでしょう。 しかし、自分以外に誰も利用しないのであれば、 変数の利用用途も分かっているので、 全部を全部そうする必要はないと思います。

notnot
質問者

お礼

getしか定義しない場合はもちろん、publicにしない意味はわかります。質問は上記のようなget/set両方を定義した場合との比較の意味でした。 少なくとも、setの方はおっしゃるように、後で値の正当性チェックを追加できるというメリットがありますね。納得しました。ありがとうございます。 rubyだと、とりあえず attr_accessor :a と定義しておけば、obj,a= で代入できて、後で必要があれば a= メソッドを定義しなおせばいいので、あまり気にしたことはなかったです。やっぱり後付けでオブジェクト指向化した言語はいろいろと不便ですね。

その他の回答 (1)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

月並みですが、 やはり、隠蔽性、抽象性を高くするというような意味かと思います。

notnot
質問者

お礼

ありがとうございます。 #2の方の回答で納得しました。

関連するQ&A

  • phpにおいて、クラスのメソッド名を定義する際に、

    phpにおいて、クラスのメソッド名を定義する際に、 メソッド名を変数で与えることはできないのでしょうか? 例えば、下記のようなものを考えています。 class ClassA { foreach( array('AA', 'BB', 'CC') as $val ) { function set{$val}($arg) { $arg = $arg + 1; return $arg; } } しかし、これではうまくいかないようです。 一方、メソッドを用いるときには、 このような変数展開ができるようです。 ですので、定義のときにもやり方があるのでは・・?と思い、 質問させていただきました。 宜しくお願い致しましう。

    • ベストアンサー
    • PHP
  • 同じ名前の変数…

    数日前からPHPをはじめた者です。 クラス変数(という呼び方が適切かは??)と、その変数に値をセット/ゲットする関数を内包するクラスを作ってみたのですが、それに関してどうもピンと来ない部分があるので質問させてください。 以下がソースです。 class sample{ var $hensu; function set_hensu($str){ $hensu = $str; } function get_hensu(){ return $hensu; } } 上記クラスを使って値のセット/ゲットをしようとしたのですが、結果は×でした。 ファンクション内の変数を、thisで指定するとうまく行きました。 最初に指定した変数と、ファンクション内の変数を同一のものだと認識させるには、ファンクション内でのthis指定の他に方法は無いのでしょうか? もしくは、ファンクション内で書いた変数が新しい変数だと認識させない方法とか…。 無いなら諦めます。よろしくお願いします。 また、直接質問とは関係ないのですが、 どうしてPHPは変数名を書いただけで変数が作られてしまうのでしょう。メリットは何ですか? 分かりづらくて戸惑ってます。

    • ベストアンサー
    • PHP
  • templateメソッドパターンで抽象メソッドを定義する意義

    こんにちは。 テンプレートメソッドパターンで、例えば、 class oge { abstract function a(); abstract function b($param); final function tempMethod() { $this->a(); $this->b($param); } } とした場合、抽象メソッドの定義は意味があるのでしょうか? なぜなら、tempMethod()中でa()もb($param)も呼び出してますんで、 わざわざ抽象メソッドとして定義しなくてもサブクラスで実装しないとどっちみち動きません。 抽象メソッドの定義の意義を教えてください。

    • 締切済み
    • PHP
  • 引数の違うメソッド

    PHPで同名で引数の違うメソッドを作成したいのですが、可能でしょうか? <?php class Test { var $test_str = ""; function set($str){ $test_str = $str; //$this->$test_str = $str; // どちらでも良い? } function Test() { // 引数なし } function Test($str) { // 引数あり $this->set($str); } } $obj = new Test(); ?>

    • ベストアンサー
    • PHP
  • phpのthis

    a.phpを作成しました。 thisによるアクセスが可能かと思ったのですが、やはりできないのでしょうか。 ===a.php==== <?php $val = 1 ; method(); function method(){ echo $val; echo $this -> val; } ?> ===a.phpここまで===== 別のphpファイル(try.php)には以下内容を記述しました。 ===try.php=== <?php class User { private $id; public function get_id(){ return $this->id;} } public function set_id($id){ $this->id=$id; } ?> 質問: なぜ、 「try.phpでは、$idにthisでアクセスできるのでしょうか? (returnの違いかと思いましたが、set関数はreturnがないのでretrunでもないと思っています。) a.phpでは、thisで valにアクセスできないのでしょうか?」 try.phpは、classを付けてクラス作成しているから、$idにthisでアクセスできるのでしょうか? ご教授お願いします。

    • ベストアンサー
    • PHP
  • クラス、メソッド、プロパティ、変数などの意味は?

    いろんなサイトやネットでいろいろ調べたのですが、 よく分かりませんでした。自分なりに考えたことですが、 (1)~(6)の用語の内容とコード上での色付けは正しいでしょうか? (1)クラス(緑枠) コンストラクタ、メソッド、プロパティを一括りにまとめたパッケージのこと。 つまり、functionの【{】と【}】の間にあるもの。 (2)オブジェクト(青枠) 関数。すなわち「複数の物や動作を入れる物」。 つまりfunctionで始まるものをオブジェクトと呼ぶ。 (3)コンストラクタ(= クラス名または関数名)(紫枠) 「構築子」のこと。オブジェクトを作る名前の部分。 つまりfunction直後に付ける関数名(クラス名)をコンストラクタと呼ぶ。 (4)プロパティ(赤枠) 「特徴」のこと。 つまりfunction内で指定された変数(var b)をプロパティと呼ぶ。 function a(){var b;}; (5)メソッド(水色枠) 「動作」のこと。 つまりオブジェクト(functionで始まるもの)が 変数(var b)に指定された場合はメソッドと呼ぶ。 var b = function a(){}; (6)変数(灰色枠) function外で指定された変数(var b)は、変数と呼ぶ。 function a(){}; var b;

  • PHP4でのSmarty派生クラスの定義について

    こんにちはよろしくお願いします。 PHP4でSmarty派生クラスを定義する方法を教えてください。 PHP5のサンプルコードで次のようなものがありました。 PHP4では,「private」が使えないらしいとか,「__construct」ではなくてクラス名がコンストラクタ名になるとかでうまくいかないようです。どのように修正すればよいのでしょうか? また,「__destruct」はどのようにすれば良いのでしょうか?コンストラクタ名とデストラクタ名が同じでよいのでしょうか? よろしくお願いします。 <?php require_once("DB.php"); require_once("Smarty/libs/Smarty.class.php"); class MySmarty extends Smarty { private $_db; public function __construct() { $this->Smarty(); $this->template_dir="../templates"; $this->compile_dir="../templates_c"; $this->_db=DB::connect("sqlite://localhost/samples.db"); } public function __destruct() { $this->_db->disconnect(); } public function getDb() {return $this->_db;} } ?>

    • ベストアンサー
    • PHP
  • オブジェクトとメソッドの、定義の分離

    JavaScriptにて、最初にメソッド用の関数を定義しておいた後、それを複数のオブジェクトのメソッドとして利用するようにしたいのですがうまくいきません。 *************************** <html> <head> <title>test</title> <script type="text/javascript"> function a() {return this.size;} function b(s) {this.size = s;} function rectA() { this.size = 0; this.getSize = a; this.setSize = b; this.notice = function() {alert(this.getSize());} } function rectB() { this.size = 0; this.arg = 90; this.getSize = a; this.setSize = b; this.notice = function() {alert(this.getSize());} } </script> </head> <body> <script type="text/javascript"> var a = new rectA; var b = new rectB; a.setSize(12); b.setSize(250); a.notice(); b.notice(); </script> </body> </html> ************************* 要するに↑のコードのようなことをやりたいのですが、FireFox3.6と12.1で実行した限りでは、a.notice()は実行されるものの, b.notice()の段階では「this.getSize is not a function」というエラーが出てしまいます。 上手な解決法がありましたらお願いします。

  • method宣言に変数等を使って可変に宣言できるか

    method宣言時にmethod名に変数を利用して宣言する事はできるのでしょうか? ↓こんなような感じで $fuga = "test"; public function {$fuga}hoge() {  .... }

    • 締切済み
    • PHP
  • Rubyのsuperclassメソッドについて

    Rubyについての質問です。処理系は1.8.7です。 class Foo def initialize(a) @a = a end end のようなクラスを作成し、そのインスタンスを foo = Foo.new(1) のように作成します。 このとき、 foo.superclassを呼び出すと NoMethodError: undefined method `ancestors' for #<Foo:0x2b691220cc88 @a=1> とエラーになります。 一方で class FooExt < Foo def initialize (a,b) @b = b super a end end のようにFooを継承したクラスを作り、 fooext = FooExt.new(1,2) fooext.superclass とすると => Foo とsuperclassメソッドが動作します。 このsuperclassメソッドはどこで追加されたものなのでしょうか?

専門家に質問してみよう