• ベストアンサー

インターフェイスと抽象クラスについて

daisdiceの回答

  • ベストアンサー
  • daisdice
  • ベストアンサー率100% (4/4)
回答No.2

では、これはいかがでしょうか? 下記のような形で実行時でないとクラスが決定しない場合にもinterfaceやabstractは有効かと思います。 interface Logger { public function output($msg); } class Logger_File extends Logger { public function output($msg) { // ファイルにメッセージを出力する処理 } } class Logger_Mail extends Logger { public function output($msg) { // メールにメッセージを出力する処理 } } class Logger_DB extends Logger { public function output($msg) { // DBにメッセージを出力する処理 } } $type = $_GET['type']; $classname = 'Logger_'.$type; $logger = new $classname(); $logger->output('this is test'); あとは、CakePHP,Symphonyなどのフレームワークのソースをのぞいてみるとメリットが分かりやすいかもしれません。 自分でフレームワークを作る場合にはとても重宝します。

dcx147
質問者

補足

お返事ありがとうございます。 上げてもらった例では、interface Loggerを定義しなくてもいいような気もするので メリットが見出せませんが私の知識不足もありますので、おっしゃる通りにCakePHPなどの フレームワークのソースをのぞいてみたいと思います。

関連するQ&A

  • クラス、オブジェクト、インスタンスの理解で?

    お尋ねします。 既に、バリバリオブジェクト指向でプログラムを書いている方が多いので恐縮ですが、とあるサイトのオブジェクトのサンプルを使って、下記のようにサンプルソースを書いてみました。 --以下ソース--- <?php class Nerimono { private $name; public function __construct() { $this->name= 'ねりもの'; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } $objectNerimono = new Nerimono(); $objectKamaboko = new Nerimono(); $objectKamaboko->setName('かまぼこ'); $objectHanpen = new Nerimono(); $objectHanpen->setName('はんぺん'); echo 'Nerimono オブジェクトの $objectNerimono 実体(インスタンス)を生成した。'; echo "\n"; echo '$objectNerimono の private $name に「' . $objectNerimono->getName() . '」と、既に書いたあった'; echo "\n"; echo 'Nerimono オブジェクトの $objectKamaboko 実体(インスタンス)を生成した。'; echo "\n"; echo '$objectKamaboko の private $name に「' . $objectKamaboko->getName() . '」と書いた'; echo "\n"; echo 'Nerimono オブジェクトの $objectHanpen 実体(インスタンス)を生成した。'; echo "\n"; echo '$objectHanpen の private $name に「' . $objectHanpen->getName() . '」と書いた'; echo "\n"; --ここまで--- そして、これの実行結果が下記です。 C:\Temp>php Nerimono.php Nerimono オブジェクトの $objectNerimono 実体(インスタンス)を生成した。 $objectNerimono の private $name に「ねりもの」と、既に書いたあった Nerimono オブジェクトの $objectKamaboko 実体(インスタンス)を生成した。 $objectKamaboko の private $name に「かまぼこ」と書いた Nerimono オブジェクトの $objectHanpen 実体(インスタンス)を生成した。 $objectHanpen の private $name に「はんぺん」と書いた このコメントのような解釈で、合っておりますでしょうか? 今までオブジェクト指向のメリットが全然理解できず、関数の変わった呼び出し方法としか、理解できていませんでした。 PHPは、本来のオブジェクト指向とは違うようだとは、知っているつもりです。(Pブジェクト思考?w) 間違っているところあれば、ご指摘ください。m(_。_)m PHPは、Ver 5.3.5 です。

    • 締切済み
    • PHP
  • クラスについて

    こんにちわ。以前お世話になりました。 クラスについての質問です。 DBとしてPostgreSQLを使用します。 店コード(store_cd)を入力すると、名前(store_name) をDBから取ってくるクラスを作りたいのですが、 以下のようにクラス定義をしみましたがうまくいきませ ん。すごく見当違いなことをしていたらすみません。。 どなたかよろしくお願いします。 <?PHP // コードクラス class clsCode { // メンバ(プロパティ)の宣言 var $cd; // コンストラクタ function clsCode() { $this->cd; } // デストラクタ function Destroy() { unset($this); } // 名前を求めるメソッド function getName($fltcd) { $sql="select store_name from store_basic where store_cd=$this->cd"; }

    • ベストアンサー
    • PHP
  • 抽象クラスを継承してクラスを作成の作り方が分かりません

    -------------------------------------- Employee -------------------------------------- -name : String #coin:double -------------------------------------- +getName():String +setName(String name):void +getcoin():double +setcoin(double Salary):void -------------------------------------- 抽象クラスを継承してクラスを作成 car1.java car2.java Employee.javaはIEmployeeを継承 IEmployee.javaは、メソッド"String getRoleName()を定義するインターフェース IEmployee.javaも作成 Sample.javaを実行し次の結果を得られるように作成 どなたか分かる方がいましたら教えて下さい。宜しくお願いします。

  • 連想配列、オブジェクト配列の使い分け

    お世話になります。 データベースで結果を取得する場合など、連想配列のままではなく何故、わざわざオブジェクトに格納する様な手法が使われるのでしょうか? 連想配列のままで処理するほうが早いと思いますし、それに付随するクラスファイルも多くなります。また、「結びつきを緩くして仕様変更に耐えうる様に」など聞きますが、余計複雑になってしまう様な気がしますので、メリットが今ひとつ分からず判断に迷ってしまいます。 どの様な使い分け、考え方をすれば良いかアドバイスいただけたら幸いです。 何卒、宜しくお願いします。 例) ※必要と思われる部分のみ記述しております。 ■連想配列 while($row=mysql_fetch_assoc($res)){ ~以下必要な処理} ■オブジェクト配列 while($row=mysql_fetch_assoc($res)){ $example = new Example(); $example->setName($row['name']); $example->setAddr($row['addr']); $array[] = $example } ~以下必要な処理 ○モデル class Example { private $_name = null; private $_addr = null; public function __construct() {} public function setName($name) { $this->_name = (string) $name; return $this; } public function getName() { return $this->_name; } public function setAddr($addr) { $this->_addr = (string) $addr; } ~以下省略 }

    • ベストアンサー
    • PHP
  • インターフェイス実装クラスの表示について

    /* インタフェースPlanetを実装したクラスEarth、Marsがあります。  以下の実行結果になるようにクラスAggregateへshowメソッドを  追加してください。 [実行結果] 地球 太陽系にある惑星の1つで、太陽から3番目に近い。・・・ 火星 太陽系の太陽に近い方から4番目の惑星である。・・・ */ // [Planet.java] // 実装したいPlanetクラス interface Planet {   public String getName();   public String getOutline(); } // Planetを実装したEarthクラス // [Earth.java] class Earth implements Planet {   private final String name="地球";   // getNameメソッド:戻り値String、引数無し   public String getName(){    return name;   }   // getOutlineメソッド:戻り値String、引数無し    public String getOutline(){      return "太陽系にある惑星の1つで、太陽から3番目に近い。・・・";    } } // Planetを実装したMarsクラス // [Mars.java] class Mars implements Planet {   private final String name="火星";   // getNameメソッド:戻り値String、引数無し   public String getName(){     return name;   }   // getOutlineメソッド:戻り値String、引数無し   public String getOutline(){     return "太陽系の太陽に近い方から4番目の惑星である。・・・";   } } // メインクラス // [Main.java] class Main{   public static void main(String[] args){   // Earth&Marsクラスのインスタンス化    Earth earth = new Earth();     Mars mars = new Mars();   // Aggregateクラスのインスタンス化   Aggregate aggregation = new Aggregate();   // showメソッド呼び出し:戻り値無し、引数earth・mars    aggregation.show(earth);    aggregation.show(mars); } } // [Aggregate.java] class Aggregate { // ここにshowメソッドを追加   public void show(Earth planet){     System.out.println();   }   public void show(Mars planet){     System.out.println();   }  } showメソッドに引数としてEarth planet,Mars planetを渡すというところまでは理解しています。後は星の名前と概要を表示するのですが、例えば、 showメソッド内 // ここにshowメソッドを追加 public void show(Earth planet){ String str = earth.getName(); System.out.println(str); } public void show(Mars planet){ String str2 = mars.getOutline(); System.out.println(str2); } } とすると、erathとmarsの部分が「シンボルがありません」のエラーになります。自分の認識としては、EarthクラスとMarsクラスでフィールド変数を宣言しているので使えるのでは?と思っていたのですが、全然違うようです。どなたかどちらかのコード例を表記して頂けないでしょうか?よろしくお願い致します。

    • ベストアンサー
    • Java
  • JSのクラスについて

    JSのクラスについて https://okwave.jp/qa/q9320085.html の続き >>> >するとCat.nameとなりCatクラスという箱の中に入っているnameプロパティ?いや引数という事なのでしょうか? 引数ではなくプロパティです、ここではクラス内部のローカル変数と説明しているモノです(初心者に分かりやすいか どうかは別としてプロパティと言った方が正確ですね)。 関数内部(関数が持っている)のローカル変数は ご存知ですか?、それに類似しています、この場合はクラス内部(クラスが持っている)のローカル変数と言うイメージです。 Cat.nameとなりCatクラスという箱の中に入っているnameプロパティなのですね。 nameとコンストラクタの引数があるのでthis.nameのnameも引数なのかと思ったのですが、ドットつながりなのでcatクラス(オブジェクト)の中にあるnameプロパティ という事ですね。 関数のスコープの中で宣言する変数のことですよね。 巻き上げが起こる変数ですね。 これとクラス内の変数はほぼ同じ挙動をするという事ですか? するとスコープがクラスにもあるのでしょうか? 巻き上げも >>> >なぜこの例えはこんなわかりにくいことをしたんですかね? 恐らく同じ名前でも「this.」が付いてるか付いてないかで区別できるので、同じ名前でもコンフリクト(衝突、競合)せずに使えると言う例を示したかったのかもしれません。 thisで別の引数?の物と区別できるという事を伝えたかったのですね。 ただ二つはコンストラクタの引数でthis.nameだけはそもそも引数ではなくプロパティなので、 仮にかぶっても問題ないのでしょうね。 >>> >変数と似ている箱で 変数と違う箱と考えて下さい。 オブジェクト、クラス、関数、変数などいろいろな箱がありこんがらがるのですが、 もしかしてこれらはすべて変数なのですか? つまり箱はすべて変数で、これらは少し個性の違う変数なのでしょうか? >>> >特殊な箱でなんでも好きに入れ替えできず、 >入れられるものと入っていなくても良いものが固定されている箱という事でしょうか? >つまり変数と違ってコンストラクタが絶対に入っている箱なのですね。 初期設定が必要ないなら、コンストラクタは必要ないようです。 クラスをインスタンス化したい場合のみコンストラクタは必要で、 インスタンス化が不要なクラスなら必要ないという事でしょうか? ただクラスはインスタンス化しないと利用できないので、 文法上はコンストラクタなしでも良いが、実際はそのようなことはあり得ないという事でよいでしょうか? またインスタンス化と初期設定の違いが判らないのですが、イコールと考えてよいでしょうか? >>> >入れられないものもあるのですか? クラス内クラスは無理なようです。 それ以外はオブジェクトのように入れられるのですね。 >>> >var コンストラクターの「name」= my cat;という事ですかね? その説明は変な感じです、実際のプロセスを考えて下さい(「my cat」ではなく"my cat"文字列です)。 new Cat("my cat") ←ここでコンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれます。 constructor(name) {this.name = name} とは constructor関数の中に中カッコ内の式があり、 catクラス内のnameプロパティにconstructorの引数nameを代入するという事ですよね。 不思議なのはconstructorの引数nameを代入する部分なのですが関数の引数を代入するというのは初めて見ました。 仮引数nameなので constructor(name) { var name = "my cat"; this.name = name } という事ですよね。 つまり下記のcatクラスの引数が実引数になるという事ですよね。 //インスタンス作成 var clsObj = new Cat("my cat"); 関数であれば関数の呼び出しにある引数が実引数として代入されますが、 クラスの場合はconstructor関数の呼び出しにある引数ではなく クラスのインスタンス化にある引数が実引数として代入されるというルールなのですね。 constructor関数の呼び出しがないのが不思議でしたが、 constructor関数は定義するだけで呼び出しはしなくても実行されて、インスタンスを作成するのですね。 そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 >>> 「インスタンスの引数」と言うのは違います。 new Cat("my cat"):Catクラスに実引数"my cat"文字列を設定しnewすると、コンストラクターの「name」仮引数に"my cat"文字列が代入され、「constructor(name) {this.name = name}」が呼ばれ、インスタンスが生成されます。 こちらも上記の説明で正しいでしょうか? >>> コンストラクターが在る場合もコンストラクターは初期設定だけです。 クラス"設計図"からインスタンス"実態"を作成すると言う事で、例えるなら十徳ナイフの"設計図"から十徳ナイフの"実態"を作成すると言うイメージして下さい。 (十徳ナイフの"実態"を作成しても)十徳ナイフが置いてあるだけでは何も役に立ちません、十徳ナイフは使ってこそ役に立つ訳です、例えば十徳ナイフの「栓抜き」(機能)を使うと言うのが「栓抜き」メソッド、「缶切」(機能)を使うと言うのが「缶切」メソッドに対応すると言うイメージです。 なるほどクラスがナイフの設計図で、constructor、newクラス名がナイフを作るための作業で、 ナイフがインスタンス化されたオブジェクトですが、この時点では何のメリットもないのですね。 インスタンス化されたオブジェクトを使う作業がメソッドという事ですね。 下記例ですとnew Cat("my cat");がナイフを具現化する作業(constructorもこれに当たる?)で、 実際に使うメソッドはここにはないのですかね? class Cat { (name) {this.name = name} meow() {alert( this.name + 'はミャオと鳴きました' )} } //インスタンス作成 var clsObj = new Cat("my cat"); //インスタンス(オブジェクト)の中身を出力 console.log(clsObj); >>> 仮引数とローカル変数(プロパティー)とは違います。 ローカル変数(プロパティー)はクラスの箱の中に定義されるモノです(添付画像参照)。 上記でも記載した、仮引数と実引数が実質var name = "my cat";というローカル関数と同じ結果になるという意味で書いたのですが、 それでも違うでしょうか? もちろん同じものではないですが、実質同じ結果にはなるのですよね。 >>> そして constructor(name) { var name = "my cat"; this.name = "my cat" } となりプロパティnameに文字列mycatが代入されるのですね。 下記が同じ結果になるという意味なのでしょうね。 >>> 申し訳ございません訂正です、引数を引数としか考えてませんでしたが、ローカルと言われれば確かに引数もローカル変数でした。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ちなみに(コンストラクター以外は)クラスの構造がインスタンスの構造に反映されます(添付画像参照)。 関数のローカル変数とインスタンスのプロパティーは類似していますが、インスタンスのプロパティーは値が保持されます。 ここがよくわからないのですがconstructor(name)のnameは引数ではなくプロパティなのですか? 見た目は引数に見えますが、違いとしてはプロパティは値が入れられる箱であり、 仮引数はローカル変数名でしかなく、ローカル変数そのものではないので、箱ではなく、値を入れられないのですかね?

  • 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
  • php クラス

    クラスの勉強をしているのですが、 記憶寿命をfunctionの中で完結させsample2以降でも同じ変数などを使えるようにするため定義済み関数内でクラスを処理したいのですが下記のエラーが出てしまいます。 functionの中でクラスを簡潔させるにはどのようにすればよいでしょうか?また、これはなぜエラーが起きているのでしょうか? function sample1(){ $pr=new parson; $pr->name="鈴木"; $pr->age=56; print $pr->getname(); print $pr->getage(); class parson { public $name="鈴木"; public $age=56; function getname(){return $this->name;} function getage(){return $this->age;} }} sample1(); Fatal error: Uncaught Error: Class 'parson' not found in hoge/class.php:11 Stack trace: #0 /hoge/class.php(27): sample1() #1 {main} thrown in /hoge/class.php on line 11

    • ベストアンサー
    • PHP
  • javaのクラスなど

    現在次のようなクラスを作成していて、自分なりに作ってはみたもののうまく分かりません。 どこが間違っていてどのように修正したらよいのか、詳しく教えてください。 9と10は分かりませんでした。 (1) 次に示す内容を満たすバー(Bar)クラスを作成せよ。 1. バーの右端のx座標(=バーの長さ)、バーの名前を扱う2つのprivateなインスタンス変数を持つ。 2. バーの総数を扱うprivateなクラス変数を持つ。ただし、 ここでいう総数とは、(1)コンストラクタで作成したもの、(2)代入操作で作成したもの、の両方を含む。 3. 引数無しのコンストラクタが呼び出されてバーオブジェクトが作成されると、そのバーのx座標は0以上400未満でランダムに決定され、名前は文字「A」とランダムに決定された0以上10000未満の整数が連接されたものに決定される。 4. バーのx座標を設定するインスタンスメソッドを持つ。 5. バーの名前を設定するインスタンスメソッドを持つ。 6. バーのx座標を取得するインスタンスメソッドを持つ。 7. バーの名前を取得するインスタンスメソッドを持つ。 8. 作成されたバーの総数を取得するクラスメソッドを持つ。 9. 作成されたバーの総数を1増やすクラスメソッドを持つ。 10. 作成されたバーの総数を1減らすクラスメソッドを持つ。 こちらが作ってみたものです。 class Bar{ private int x; private String name; private int count; private Bar(){ x=0; count=0; name=""; } public void Bar(){ x = (int)(Math.random()*400); name = "A" + (int)(Math.random()*10000); } public void setBar(int bx){ x=bx; } public void setName(String nm){ name=nm; } public void getX(int bx){ } public void getName(String nm){ } public void getCount(int c){ } }

    • ベストアンサー
    • Java
  • javaプログラムのクラス図など

    「下記のプログラム例のクラス図を描き、プログラム例にはクラス図に対応するブロックにブロックコメントを挿入しなさい。最後にプログラム例でオブジェクト指向の三大要素がどのように実現されているかを説明してください。」 の部分が3週間自分なりに調べたりしたのですが全く分からなく このように質問している恥ずかしい状況です(>_<) 正直言って、明日までの課題です。。。 人生がかかっている言うと大袈裟に聞こえるかもしれないんですが 正直その通りなんです。。。 お力添えしていただける方を探しています。 どうか、お助けください。。。。。。 問題 オブジェクト指向の三大要素についてまとめなさい。次に、下記のプログラム例のクラス図を描き、プログラム例にはクラス図に対応するブロックにブロックコメントを挿入しなさい。最後にプログラム例でオブジェクト指向の三大要素がどのように実現されているかを説明してください。 Animalインタフェース public interface Animal { public abstract void bark(); } ーーーーーーーーーーーーーーー Petインタフェース public interface Pet extends Animal { public String getName(); } ーーーーーーーーーーーーーーー Catクラス class Cat implements Pet { private String name; public Cat(String name) { this.name = name; } @Override public String getName() { return name; } @Override public void bark() { System.out.println("ね こ:ニャー"); } } ーーーーーーーーーーーーーーー Dogクラス class Dog implements Pet { private String name; public Dog(String name) { this.name = name; } @Override public String getName() { return name; } @Override public void bark() { System.out.println("い ぬ:ワン"); } } ーーーーーーーーーーーーーーーー Duckクラス class Duck implements Pet { private String name; public Duck(String name) { this.name = name; } @Override public String getName() { return name; } @Override public void bark() { System.out.println("あひる:ガーガー"); } } ーーーーーーーーーーーーーーーー Frogクラス class Frog implements Pet { private String name; public Frog(String name) { this.name = name; } @Override public String getName() { return name; } @Override public void bark() { System.out.println("かえる:ケロケロ"); } } ーーーーーーーーーーーーーーーー PetTestクラス public class PetTest { public static void main (String[] args) { Pet[] pets = {new Cat("タロー"), new Dog("ミケ"), new Frog("ケロ"), new Duck("ドナルド") }; System.out.println(); for(Pet pet: pets) { System.out.printf("\t%8s\t", pet.getName()); pet.bark(); } System.out.println(); } } ーーーーーーーーーーーーーーーーーー 実行結果がこうなります D:\Work >java PetTest タロー ね こ:ニャー ミケ い ぬ:ワン ケロ かえる:ケロケロ ドナルド あひる:ガーガー -- Press any key to exit (Input "c" to continue) -- 上の問題なのですが もし解くことができる方がいましたら お願いします_(._.)_