PHPでオブジェクト指向プログラミング
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2005/04/17(日) 16:55:57ID:iM4mgYnJPHPによるOOPについて語りましょう。
0666nobodyさん
2005/08/28(日) 11:23:32ID:???通常はする必要なし。
0667nobodyさん
2005/08/28(日) 11:59:04ID:???さんくすちんぽ
0668nobodyさん
2005/08/30(火) 10:18:32ID:???パフォーマンスは関係ない気がする。
あると主張するなら字句解析や構文解析のどういう部分でメリットがあるか
理由を説明して欲しい。
awkとかpythonとか$の必要ないスクリプト言語は現にあるし
それらと比較しても特に$にメリットがあるわけじゃない
php は perl の真似をした
perl は sh の真似をした
それ以上でもそれ以下でもない
0669nobodyさん
2005/08/30(火) 10:50:09ID:???> あと、$なし言語は
> print "abc $def ghi";
> みたいな真似ができない。
変数の文字列埋め込みなんてフォーマッティングや文字列連結で代替できるじゃん。
0670nobodyさん
2005/08/30(火) 12:38:03ID:???ぱっと見分かりやすいからだろ
0671nobodyさん
2005/08/30(火) 13:11:54ID:4hyOkdNt>$なし言語は
>print "abc $def ghi";
>みたいな真似ができない。
そういうメリットを主張する割には
defineで定義した名前は""内で使うことができないんだよな。
この辺のいいかげんさがPHPの特徴。
0672nobodyさん
2005/08/30(火) 21:44:33ID:???俺もそう思う。機械にとってどうって事じゃなくて、人にとってどうかだと思う。
ただでさえ素人(俺含む)が多いPHPerにとって、ぱっと見「あ、これ変数ね。」って思えるのは結構重要だと思う。
0673nobodyさん
2005/08/30(火) 22:05:46ID:???まぎらわしいんじゃボケ!
0674nobodyさん
2005/08/31(水) 12:00:09ID:???php は perl の真似をした
perl は csh の真似をした
cshはshの真似をした
の方が正確ではない?
>>669
> 変数の文字列埋め込みなんてフォーマッティングや文字列連結で代替できるじゃん。
TMTOWTDI。
それらに比べてタイプ量が少なく済み、見通しがいいのは充分メリットだと思うが。
>>671
> defineで定義した名前は""内で使うことができないんだよな。
そりゃそうだろ……。""の中の[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* を全部パースするのか?
第一""内で使えなくて困る場面なんてそんなにあるか?
0675nobodyさん
2005/08/31(水) 12:29:45ID:???0678nobodyさん
2005/09/02(金) 05:16:07ID:???interfaceで定義したいんだけど
Javaのstatic final変数と違ってconstが使い物にならず。
PHPでJavaのstaticイニシャライザ、インスタンスイニシャライザを
真似することは不可能なんだろうか?
static メソッドを定義してSingletonパターンでなんとか
誤魔化してやるしかないんだろうか。
0679nobodyさん
2005/09/02(金) 05:18:08ID:???$をつけた理由はテンプレートとして使いたいからかと思われ。
Java用テンプレートエンジンJakarta Velocityは
テンプレート変数は$で始まるようになっている。
0680nobodyさん
2005/09/02(金) 05:23:22ID:???> >>654
> exit;
> $exit;
>
> $some_func();
> some_func();
>
> print(abc);
> print($abc);
>
> どれも$のあるなしで挙動が違うだろ。あと、$なし言語は
>
> print "abc $def ghi";
$がつくものとして上にあげたJakarta Velocityのようなテンプレートエンジン
として使うメリットはあるが、$なし言語でも
正規表現などが盛り込まれた関数や特殊な関数を使えば
その手の再現は簡単にできる。
JavaのTextFormatというクラスを思い出した。
あれを使い、かつリフレクションAPIを使えば、文字列中に$が現れたら値に変換してから表示する
というメソッドを作ることもできる。リフレクションは重たいけど。
0681nobodyさん
2005/09/02(金) 05:30:42ID:???これはまずい。
PHPはデフォルトでは配列は値渡しなのか?
Javaやりすぎて、デフォルトでは
配列やオブジェクトは参照渡しのみであり、基本型(プリミティブ型)のみ値渡し
であってこともあり、
PHPでは値渡しなどもできることを忘れていた。
やばい、バグが。
PHPではメソッドの引数にはC/C++のように値渡し参照渡しの設定はできないんだろうか?
Javaでは上と同じように、プリミティブ型のみ値渡しで
他(オブジェクトと配列)は参照渡し。
どうしても値渡しをしたい場合はObject#clone()を使ったり、オーバーライドしたりする。
PHPにはJavaのObject#clone()メソッドに相当する機能cloneもあるんだね。
これでPHPで深いクローニングができるわけか。
0682nobodyさん
2005/09/02(金) 05:33:03ID:???インタプリタ言語としてつかうならそうだけど、
JavaやC#のようなコンパイラ言語でかつ、VM上でさらにJITコンパイラによって
中間言語をさらにその場でコンパイルするような言語だと
それは最初の開発者によるコンパイルで最適化されるから
どうでもいいような気がする。
Zendエンジンなんてものもあるけど、タダで使えればねえ。
0683nobodyさん
2005/09/02(金) 07:20:11ID:MBSmrOidごめん、何が言いたいかよく解らん。。
取り敢えず疑問は解決したの?
0684nobodyさん
2005/09/02(金) 09:20:10ID:???歴史的に見れば、裸の文字リテラルや予約語と衝突しないのが当初の目的でしょ。
shで裸の変数を許したらコマンドや引数はどうやって指定すりゃいいんだ。
あとは$があるとパーサが変数かどうかの判定に困らないので、文法の幅が広がる。
phpのexitみたいな括弧なしの言語構造や、Perl関数の戻り値にスカラが指定できるような
芸当は$なし言語だと厳しいでしょ。
0685nobodyさん
2005/09/02(金) 09:22:02ID:???0686nobodyさん
2005/09/02(金) 11:57:33ID:???> PHPはデフォルトでは配列は値渡しなのか?
値渡しだけど、配列の要素を書き換えない限り、内部的には配列はコピーされないのでパフォーマンス的には参照渡しと同じ。
文字列やオブジェクトも同様。
> PHPではメソッドの引数にはC/C++のように値渡し参照渡しの設定はできないんだろうか?
&をつければ参照渡し。その点はC++に似てる。
C++では配列ならC式の参照渡し(アドレスの値渡し)で十分だけど。
とりあえず疑問文にだけコメントしといた。
0687nobodyさん
2005/09/03(土) 00:10:51ID:???0688nobodyさん
2005/09/03(土) 09:36:19ID:JcQXpRDzたとえば。クラスtest,
メソッドtest($t){$this->t}と定義した場合
$test= class test;
でメソッドのひきすうに10を渡した場合
$test->test(10);
これでなにも表示されないんですね・・・なんかつかいずらい
いちいちメンバーを定義して
public $tみたいに・・・めんどくせえ・・・
0689nobodyさん
2005/09/03(土) 10:52:27ID:???public $t;書いてもそのままじゃ何も表示されないとおもうけど。
echoはないわ、$this->tに値いれてないわ。おかげで主張の内容がさっぱりわからん。
まずどの言語から移行したわけ?メンバ定義なしでメンバを使える言語ってまさか・・・?
0691nobodyさん
2005/09/03(土) 12:22:13ID:???php5では
function __construct() { }
が優先される
<?php
class test {
function __construct() {
echo "testクラス作成<br>\n";
}
function test($t) {
echo $t;
}
}
$test = new test();
$test->test(10);
?>
こんなことも出来る
0692nobodyさん
2005/09/03(土) 16:19:09ID:???__construct()が優先されるけど、書いてないならこの場合test($t)が呼ばれるよ。
んで、インスタンス化した際に引数つけてないとWarningがでる。
>>688で書いてる、
$test= class test;
って書き方初めて見たのだが、それエラーするだろ?
それとも俺はPHP5しか知らないのだけど、4ではその書き方出来るの?
0693nobodyさん
2005/09/03(土) 16:46:21ID:JcQXpRDz俺がいいたかったのは
class test;
{ pubclic funciton tes($a);
{
echo($this->a);
}}
で
st= new test();
ここでメソッドをよびだした場合
st->tes(10);なにも記述しなてくて
つまりメソッドの場合$this->aってできないんだな
public $a; $this->a=$a
みたいな・・二度手間だな・・・まぁいきなり$aならこれでも表示するんだが
本みるとこの二度手間をしてる・・
0694nobodyさん
2005/09/03(土) 16:47:21ID:???> $test->test(10);
と書いているので、コンストラクタの話題を意図していたわけじゃないんだろうけどな。
>>692
> 4ではその書き方出来るの?
んなわきゃないw
PHP Parse error: parse error, unexpected T_CLASS in (ry
極めて真っ当なエラーですな。
0695nobodyさん
2005/09/03(土) 17:01:56ID:???その本で何を解説してるのか知らないが、大方
・プロパティ名とメソッドの引数名は同じでも問題なし
・public $a と $this->a の「a」は同じ変数を表すが tes($a) の「a」は全く別の変数
ってな感じの内容じゃないの?
どこが二度手間なわけ?
0697nobodyさん
2005/09/03(土) 18:15:04ID:JcQXpRDzてことは
クラスの中に
メソッド pubulic funciton hell($a){ echo($a."さんこんにちは");}
こういう使い方はできるんだね。現にやったらできたけど
なんかPHP5の本ではさやたら$this->
って感じでやってるから。
PHP5の本どうでもいいけど少なすぎ><
0698nobodyさん
2005/09/03(土) 18:18:07ID:JcQXpRDz本ではさ
public $a;
pubulic funciton hel($a){
$this->a=$a
echo($this->a."さんこんにちは")}
みたいな使いかたをしてたから
なんでこんな二度でまをふんでるんだろうかと
本がわるいのかもしかして
0699nobodyさん
2005/09/03(土) 18:22:35ID:JcQXpRDz俺みたいなやつの質問にこたえてくれて
会社でPHPつかえるやついなくてな、皆javaばかりで
おれだけPHPだから肩身せまくてな
これからもよろしくたのむよ
0700nobodyさん
2005/09/03(土) 18:53:52ID:???$aをメソッド内のローカル変数として使いたいのか
それともフィールド変数として他のメソッドからも使いたいのか
どっちが目的なのかわからん。
0701nobodyさん
2005/09/03(土) 19:00:47ID:???この程度の内容にPHP4、PHP5、Javaで違いはないんだが(書式以外で)。
オマイがカスすぎて他の社員から相手にされてないだけではないのか。
0702nobodyさん
2005/09/03(土) 19:15:26ID:???>会社でPHPつかえるやついなくてな、皆javaばかりで
>おれだけPHPだから肩身せまくてな
オマエ、どうみてもPHP使えないだろ? 下手するとPHPだけじゃなくプログラミング自体素人か。
Javaは絶対習得できそうにないからPHPでもやらせとけ、って感じしかしないのだが。
0703nobodyさん
2005/09/03(土) 19:37:49ID:fR+7vSEm本の読み方を間違ってる。
0704nobodyさん
2005/09/03(土) 19:39:05ID:JcQXpRDzもともと営業ではいったからな
プログラミング歴は3週間目だ。
これで月給38万ももらってていいのか。
0705nobodyさん
2005/09/03(土) 20:12:15ID:???営業で入ったにしても日本語が下手すぎるね。
まぁ給料貰えるうちに頑張れ。
なんでthisを多用するかって事だけど、先の例だと
setterっぽく使いたかったのかな?変数publicだけど・・・。
その本を読み進めて行くと、多分その疑問は解凍されると思うよ。
0706nobodyさん
2005/09/03(土) 23:51:44ID:???インピーダンスミスマッチについてどうお考えですか?
仕事でPHPでオブジェクト指向で進めようとしていますが、
PHPの効率のよさはオブジェクト指向ではないやり方によるものだった
ってことはありませんか?
0707nobodyさん
2005/09/03(土) 23:59:36ID:???営業で入って、プログラミング歴3週目で、>>688 で書いている
"最近PHP5に移行したんだが" が激しく一致しない。。。
0708nobodyさん
2005/09/04(日) 01:10:09ID:???3週間前PHP4の本渡されて勉強した後、最近新たにPHP5の本渡されて勉強しはじめたんでないか?
彼の中ではすでに「最近PHP5でクラスを自作しました」とかになっていると思われ。
0710nobodyさん
2005/09/04(日) 03:05:09ID:???いい身分だな。
何も教えてやりたい気分も萎えそうだが
オブジェクト指向を理解していない奴と一緒にソフト開発することほど
ウザイことはないから少しだけ教えてやる。
0712nobodyさん
2005/09/04(日) 03:07:29ID:???PHP5でオブジェクト指向ををやるのに本が少なすぎる?
ならJavaの本を買え。
結城浩の「Java言語で学ぶデザインパターン入門」
これ嫁。これ読めばPHP5で無理矢理オブジェクト指向するよりも
オブジェクト指向は素早くすんなり理解できる。
何と言ってもオブジェクト指向といえばJavaと言われているくらいだからな。
0713nobodyさん
2005/09/04(日) 03:12:09ID:???純粋論者はインスタンスフィールド$aをprivateにすべきだと主張する傾向にあることをよく覚えておけ。
そのときは$aに対するgetter/setterを定義するることをお忘れ無く。
PHP5からは__getや__setなんてものもあるらしいな。
どんなメリットがあるのかわからんので
自力でgetA(), setA($a)を定義してはいるが。
メソッド引数で定義されている$aはローカル変数で
フィールドの$aとは異なる。
そのときの重複を避けるために$this->aという記法を用いる。
0714nobodyさん
2005/09/04(日) 03:14:50ID:???Javaのfinalに相当する最初の一回しか代入を許されない変数を定義できないのだろうか?
でないと不変クラスを作れない予感が。
0715nobodyさん
2005/09/04(日) 03:16:30ID:???機能が強化されてもnamespaceが使えないのが非常に残念だ。
Facadeパターンなどを実現しづらい。Javaですっきりと実現できる
デザインパターンがPHP5ではあまりにも中途半端でアクセス権の管理があまりにも杜撰になる。
0716nobodyさん
2005/09/04(日) 04:32:10ID:???PEARみたいな公式の出すらPHP4との互換性保持のため
ほぼ全てのフィールドがvar宣言。メソッドも同様。
0717nobodyさん
2005/09/04(日) 06:15:04ID:???0718nobodyさん
2005/09/04(日) 08:21:13ID:???無理にJava目指すことは無いんじゃないかな。
OOPを知りつつ、OOPの考え方で
OOPじゃない簡単な実装だってできるだろうし。
0720nobodyさん
2005/09/04(日) 08:27:14ID:???0721nobodyさん
2005/09/04(日) 10:11:49ID:???できるようだが。
ttp://www.php.net/manual/ja/language.oop5.final.php
0722nobodyさん
2005/09/04(日) 17:13:11ID:???PEAR::MDB2というのがあるが、
今ベータ版。
MDB1がPHP4対応であるのに対してMDB2はPHP5対応。
よってこれからのPEARはPHP5によってすべて生まれ変わる。
0723nobodyさん
2005/09/04(日) 17:20:23ID:xhmaGAtHあのーfinalなクラスやメソッドを定義できるのは知ってるんですけどー
やりたいことはfinalなフィールド(メンバ変数、プロパティ、属性)やローカル変数を定義したいんですけどー
constしか使えないんですかぁ?
const CONSTANT = 'aa';
とかはできるんだけどさあ。
const CONSTANT2;
と宣言だけしておいて
コンストラクタで
public __construct(Type $constant){
$this->CONSTANT2 = $constant;
}
と後から代入するってことができないんですけどー
こういうこともできなくて困ってるんですけどー
const CONSTANT3 = CONSTANT2.'連結'
0724nobodyさん
2005/09/04(日) 17:23:35ID:???pulic void doMethod(final Type type){
type = "aa"; //typeはfinal宣言されているので
//あとから代入するとエラーになるように、誤作動防止機能
//として使える。
}
これをPHP5でやると?
pulic function doMethod(constant Type $type){
$type = "aa"; //typeはfinal宣言されているので
//あとから代入するとエラーになるように、誤作動防止機能
//として使える、はずなのだが。
}
見事にエラーですか。
困っちゃったねえこりゃ
0725nobodyさん
2005/09/04(日) 17:24:52ID:???そこでPerl6ですよ。
ParrotVirtualMachineといい、コンパイラといいバイトコードといい
もろJavaのパクリですが。
0726nobodyさん
2005/09/04(日) 21:26:38ID:???Singletonでなんとかならんか?
ってか、phpならそうやって使うのが普通だと思うが?
なぜjavaに拘る.
# finally欲しいなぁ
0727nobodyさん
2005/09/04(日) 21:35:22ID:???同意。
Javaはコンパイル型。PHPはインタプリタ型。
だから同じ書き方・動作じゃないのは当たり前なんだけど。
例えば Javaでいう Interface みたいのを
スクリプト言語に入れるのは、なんか違うよね。
そういうのはコンパイル型の言語で素直にやりなよ、ということ。
0730nobodyさん
2005/09/05(月) 04:03:31ID:???JavaソースをPHP5ソースに変換するツールはおらぬのか?
0732nobodyさん
2005/09/05(月) 22:06:33ID:???いらないんじゃなくて、ナンセンスだってことでしょ。
スクリプト言語なのに、メソッド実装を強制するような事が。
実行時に文字列を読み込んで、
その場でインタプリタがクラス作っちゃうような事もできるのに。
Interfaceみたいのは、別にあっても良いと思うけど。
速度に問題出なければ。
0733nobodyさん
2005/09/05(月) 22:30:28ID:???Java使いがPHPを使う場合、またはPHP使いがJavaを学ぶ為って感じがする。
自分がそうだったし。
PHPでOOPだのDIだのなんだのすると速度的にかなりマイナスだしね。
0734nobodyさん
2005/09/05(月) 22:42:44ID:???静的型付けか動的型付けかということのような気がする。
0735nobodyさん
2005/09/05(月) 23:35:49ID:???0736nobodyさん
2005/09/06(火) 00:39:18ID:???0737nobodyさん
2005/09/06(火) 01:00:02ID:???0738nobodyさん
2005/09/06(火) 01:11:32ID:???0739nobodyさん
2005/09/06(火) 01:17:11ID:???setXXX(), getXxx() を__call()でオーバーロードするとか、そんな感じですかね。
DAO設計するときに役立ちそう。
0740nobodyさん
2005/09/06(火) 03:01:57ID:???dev-mlでもそのへんの改善案を検討しているみたいだけど。
基本的にPHPのマジックメソッドはどれもちょっと抜けてて使いにくい。
0742nobodyさん
2005/09/07(水) 12:48:27ID:???require()が無駄にリストアップされてしまう問題を
__autoload()によって解決できるとおもったらそれできんのかい?
>>740もオーバーライドができないってことは、かなり痛すぎる予感。
Javaの真似をして
とりあえず、すべてのクラスの頂点たるObjectクラスを実装して、
そのクラスにとりあえず__autoload()を
入れておくってか。
以後、すべてのクラスは、継承宣言をする予定がないときは、
かならずObjectクラスを継承するように予定変更する、と。
で、ObjectクラスにはJavaのObjectと同じように、
hashcode(), equals(), finalize(), wait(), notify()などを実装する。
少なくとも、equals()は重要。
Comparableインターフェースなども作っておく。でcompareTo()メソッドも
実装できるように。Cloneable, Serializableインターフェースも。
__autoload()を無理矢理オーバーライドするなら、
これしかないか?
__autoload()を他のメソッドでラップし、そのメソッドをサブクラスオーバーライドする。
でオーバライドしたらまたそのサブクラス内で__autoload()を実装し、オーバーライドした
メソッドを呼び出す。
っていうやりかたはうまくいかんか?
0743nobodyさん
2005/09/07(水) 13:08:31ID:???PHPで多重継承が必要な場面に遭遇したことないけど。
それが>>732の言わんとしてることじゃないの?
>>742
__autoloadのラッパ・・・?それじゃ__autoloadの意味ないじゃん。
ファクトリメソッド作るなら、そのメソッド内でrequireしたほうが話は早いわな。
とりあえず何を主張したいのかが不明瞭。
>>738と>>740への批判みたいなことを言いたいのだろうか?
0744nobodyさん
2005/09/07(水) 16:59:36ID:???多重継承しないように設計すれば良いだけでしょ。
Javaでしかデザインパターンしたこと無いのかも知れないけど…。
0745nobodyさん
2005/09/07(水) 21:56:51ID:???委譲や集約だけに任せるってのかい。
そっちのほうがもっとナンセンスに見えることもないか?
デザインパターンでも多重継承つかったサンプルが沢山あるのに。
それに、オブジェクトをディープコピーできるようになることを示すCloneableインターフェース、
オブジェクトを直列化できることを示すSerializableインターフェース、
これらが使えんだろ。
こういうインターフェースを定義したい場面ってのが結構ある。
あるクラスを継承したいが、すでに他のクラスによって継承されているので
これ以上継承できない、っていうとき、片方のクラスがインターフェースになっていれば助かる。
とくにマーカーインターフェースは使える。
>>732はメソッド実装を強制するためだけにインターフェースを使うつもりでいるらしいが、
マーカーインターフェースはメソッドなんかいらない。
Serializableはメソッドなんか一つもない。まさにクラスにマーカーをつけるかのように
インターフェースを実装できる。
このように、一つのクラスに、継承しながら複数のインターフェースを実装したい場合があるときに、
インターフェースは役に立つ。
デザインパターンの本を良く読んでいるならインターフェースを使ったサンプルはよく見かけると思うが。
インターフェースは便利だから使う。抽象クラスだけでは限界があるとき、
非常に役立つ。
無計画に使いすぎるとインターフェースの乱立が生じてとんでもないことにはなるが。
使い方さえ気をつければ非常に使える。
それから、定数を定義するときもインターフェースをよく使う。
実装はしないがタダ定数を置くだけ。define()を使えという意見もあるが、インターフェース名::定数名
という構文規則が守られちょっとわかりやすくなる。
0746nobodyさん
2005/09/07(水) 21:59:17ID:???インターフェースも使えないのはなにか違和感がある。
ここでクラスだけにしたら、クラスに多重継承させることを許してしまう。
というか、クラスで多重継承ができることを許さないといけなくなる。
そうするとC++のような混乱が生じ、ダイヤモンド継承とかわけのわからんことになる。
だからインターフェースは必要なんだと。
0747nobodyさん
2005/09/07(水) 22:15:56ID:???デザパタは大事だけど、PHP採用してるような現場でそこまで厳密なOOPが必要か?
とも思う。
現状のPHPが中途半端な状態にあるのは分かるけど、
中途半端なら回避すれば良いだけでしょ。
仕事でどうしてもPHP使えと言われていて、PHPの今の実装はこうです。となってる。
デザパタ知ってるなら、その考えを使って、
いま組めと言われている言語にあった、無理の無い設計をするのが普通じゃないのかな。
うまく骨抜きにして言語に合うように実装する。そんだけだろ。
0748nobodyさん
2005/09/07(水) 22:22:32ID:???「プログラミングで注意すべき部分を冗長にマーキングする」でかまわんけどなぁ・・・
ZendEngineにキャッシュが搭載されるのはPHP6からだっけ?
0749nobodyさん
2005/09/08(木) 00:05:46ID:???うむ。「インターフェイスがないと多重継承ができない」とか聞くと違和感覚える。
普段どんなインターフェイスの使い方してるのか気になったりする。
0750nobodyさん
2005/09/08(木) 00:42:45ID:???Adapterパターンとかな。(代替手段として委譲するのもあるがな)
0751nobodyさん
2005/09/08(木) 01:01:24ID:???0752nobodyさん
2005/09/08(木) 02:07:18ID:???ところがそれら作られたものを使う人(クラス)には役に立たない。
0753nobodyさん
2005/09/08(木) 02:38:21ID:???代替って言うか常に委譲の方で良いじゃん。
interface不要って事だ。
0754nobodyさん
2005/09/08(木) 02:49:08ID:???execute()を持つAというinterface
それを実装したクラスB1とB2が有ったとする。
で、利用するコード
$a[] = new B1();
$a[] = new B2();
$a[] = new C1();
foreach ($a => $obj) {
$obj->execute();
}
ここでC1はたまたまexecute()を持つAを実装でないクラス。
PHPはこれでエラーが起きない。
0755nobodyさん
2005/09/08(木) 02:55:41ID:???何をしたいのかも明確にできない。type hintingみたいな機能もあるけど
Javaと違ってmainメソッドを必ずしもクラスにする必要は無いわけだし。
0756nobodyさん
2005/09/08(木) 03:33:10ID:???まあわかってやれよ。こういうことだろ?
interface A { public function execute(); }
class B1 implements A { public function execute() { ・・・ } }
class B2 implements A { public function execute() { ・・・ } }
class C1 /* doesn't implement A */ { public function execute() { ・・・ } }
$a = array(new B1(), new B2(), new C1());
foreach ($a as $obj) $obj->execute(); // interface Aなんて初めからあってもなくても結局変わらん
つまり、PHPのinterfaceはインスタンスの型を制限する役割は全く果たせないってこった。
ただJavaライクな文法があれば、Javaに慣れている人間同士で意思の疎通や理解がしやすくなり、結果的にデザパタも組みやすくなるって面もある罠。
その点では大きな利点といえる。
しかし、飽くまで可読性・保守性に関する利点であって、PHPの言語仕様上の利点ではない。
現にPHPでデザパタは多くの場合、単に「通念的」にしか実装できないことが多いが、その限りでは文法上どんなデザパタもinterfaceなしで実装できることになる。
0757nobodyさん
2005/09/08(木) 08:45:11ID:???まあ PHP 的には以下のようにするのが限界かな。
foreach ($a => $obj) {
if ($obj instanceof A) {
$obj->execute();
}
}
もしくは duck-typing な感じで、
foreach ($a => $obj) {
if (method_exists($obj, 'execute')) {
$obj->execute();
}
}
とか。
0758757
2005/09/08(木) 08:54:45ID:???■$a をコレクションにして Iterator を使った場合
while ループの中で A obj = (A) iterator.next(); とした時に
C のインスタンスが ClassCastException で引っかかる
■$a を A の配列にした場合
配列に C1 のインスタンスを代入しようとした時点でエラー
となるわけで、どっちかっつーと PHP の扱い方のほうが便利じゃない?
0760nobodyさん
2005/09/08(木) 10:46:30ID:???だからその「便利じゃない」って点こそが肝なんだよな、結局。
書けるコードに制限を設けることで意図を明確にできるわけで。
0761nobodyさん
2005/09/08(木) 11:52:57ID:???0762nobodyさん
2005/09/08(木) 13:09:48ID:???インスタンスの型を制限する役割はないといっても
メソッドに引数で制限できるから
インターフェースはわりと使えるもんだよ
0763nobodyさん
2005/09/08(木) 15:49:09ID:???JavaならばC1の書き直し、
状況によってはinterface A自体の見直しも必要になってくる。
AやC1が外部のライブラリならその修正も困難。
(まあ、そのためにAdapterパターンがあるのかもしれないが
Adapterパターンの多用は冗長になるなどの欠点をしばしば指摘される。)
そういう点でPHPのような動的な型付け言語は柔軟性があるのだと思う。
でも>>754のコードが意図的なのかどうかというのを
コメントなしに伝える事が不可能な点が問題。
メソッドの引数で伝えるのは状況が限られる。
柔軟性か信頼性かって事だ。
0765nobodyさん
2005/09/08(木) 18:58:07ID:???■ このスレッドは過去ログ倉庫に格納されています