クラスメンバ・メソッドの継承に関する質問

このQ&Aのポイント
  • クラスのインスタンスオブジェクトで不変なクラスメンバとメソッドを定義したいが、継承クラスでエラーが発生している。
  • JavaScriptではクラス定義内部とprototypeで設定したメンバとメソッドしか継承できないため、問題が発生している。
  • 他の継承の方法を探し、ベースクラスで設定したクラスメンバとメソッドを継承したい。
回答を見る
  • ベストアンサー

クラスメンバ・メソッドは継承しない?

クラスのインスタンスオブジェクトで不変なクラスメンバとメソッドを定義したいのですが、継承クラスでエラーが出ます。 -------------------------------------------------------------------ここから function baseClass() { this.instStr = "base class instance property"; } baseClass.prototype.prtMethod = function(){return this.instStr;}; baseClass.clsStr = "base class property"; baseClass.clsMethod = function(){return baseClass.clsStr;}; base_inst = new baseClass(); alert( "baseClass:\n" + "\tinstStr = " + base_inst.instStr + "\n" + "\tprtMethod = " + base_inst.prtMethod() + "\n" + "\tclsStr = " + baseClass.clsStr + "\n" + "\tclsMethod = " + baseClass.clsMethod() + "\n" ); function upperClass() { this.instStr = "upper class instance property"; } upperClass.prototype = new baseClass; upper_inst = new upperClass(); alert( "upperClass:\n" + "\tinstStr = " + upper_inst.instStr + "\n" + "\tprtMethod = " + upper_inst.prtMethod() + "\n" + "\tclsStr = " + upperClass.clsStr + "\n" + "\tclsMethod = " + upperClass.clsMethod() + "\n" ); /* Exception: upperClass.clsMethod is not a function @Scratchpad:30 */ -------------------------------------------------------------ここまで 実行は Firefox 付属のスクラッチパッドで行いました。 期待する結果は、upperClass.clsStr がベースクラスで設定した"base class property"、upperClass.clsMethod() がその文字列を返す関数となって欲しいのです。 そもそも、Javascript ではクラス定義内部と prototype で設定したメンバとメソッドしか継承できないのでしょうか? あるいは他の方法がある?

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

  • ベストアンサー
  • JaneDue
  • ベストアンサー率75% (263/350)
回答No.1

クラス変数・関数はインスタンスではなくクラスに属するものなので「そもそも~」の通りかと。 >クラスのインスタンスオブジェクトで不変なクラスメンバとメソッド~ 厳密には無理だと思います。とりあえず function baseClass(){ var Str = "base class instance property"; return{ getStr:function(){return Str;} }; } などとして、内部の変数として隠蔽しアクセサを用意すればよいと思いますが、関数自体を上書きされればそれまでです。配布ではなく自分だけで使用する分には、 baseClass._clsStr = ~ baseClass._clsMethod = ~ のように「変更すべきでないものは_アンダーバーで命名する」などと規則を自分で決めておけば十分の様に思います。 このあたりが参考になるかも。 http://yabooo.org/archives/53

tao_0077
質問者

お礼

コメントありがとうございます。 メンバ変数や変数をオーバーライドされることに関しては問題ありません。 (質問に「不変な」と書いたのが誤解を招いたようです、ごめんなさい) new baseClass() した際にはそのインスタンスにクラスメンバが含まれているはず なのに、なぜ継承してくれないのだろう、と疑問に思った上での質問でした。 ご提示のリンクは大変参考になりました。

その他の回答 (1)

  • kuzumiHK
  • ベストアンサー率72% (132/183)
回答No.2

こんな感じでいかがでしょうか。 function baseClass() { this.instStr = "base class instance property"; } baseClass.prototype = { 'prtMethod':function(){return this.instStr;}, 'clsStr':'base class property', 'clsMethod':function(){return baseClass.prototype.clsStr;} } var base_inst = new baseClass(); alert( "baseClass:\n" + "\tinstStr = " + base_inst.instStr + "\n" + "\tprtMethod = " + base_inst.prtMethod() + "\n" + "\tclsStr = " + baseClass.prototype.clsStr + "\n" + "\tclsMethod = " + baseClass.prototype.clsMethod() + "\n" ); function upperClass() { this.instStr = "upper class instance property"; } upperClass.prototype = baseClass.prototype; var upper_inst = new upperClass(); alert( "upperClass:\n" + "\tinstStr = " + upper_inst.instStr + "\n" + "\tprtMethod = " + upper_inst.prtMethod() + "\n" + "\tclsStr = " + upperClass.prototype.clsStr + "\n" + "\tclsMethod = " + upperClass.prototype.clsMethod() + "\n" );

tao_0077
質問者

お礼

コメントありがとうございます。 日頃コーディングしているのが Python なので、prototype ベースのクラス 構築に戸惑っています。 結局、prototype で定義したものしか継承してくれないのですね。 「そういうもの」と思ってコーディングしていきたいと思います。

関連するQ&A

  • クラス継承 メンバ引継ぎとprivateについて

    「クラス継承時のメンバ引継ぎの意味」と、 「privateでオーバーライドさせた際の挙動」ついて教えてください。 class Pa{  private $level="10";  public function getLevel(){   return $this->level;  } } class Ch extends Pa{  protected $level="5"; } $ch = new Ch(); echo $ch->getLevel(); このとき、$ch->getLevel();は、 Paクラスのメソッドをchオブジェクトで見に行ってるのでしょうか? それとも、Chクラスに引き継がれたメソッドを見に行っているのでしょうか? また、このときの「$this」「$this->level」は、それぞれ何を意味しているのでしょうか? また、このときの、Chクラスの「$level」は、どういう状態(扱い)になっているのでしょうか? エラーにならないのですが、再定義扱いされないのでしょうか? 新定義扱いされてるってことでしょうか? 「privateメンバを継承した際」、どういう動きをするのか(ルールになっているのか)教えてください。

    • ベストアンサー
    • PHP
  • 【PHP】クラスを継承した際にデータ型も継承すると

    とある有料のオンライン学習サイトをつかっています。 学習項目の流れは以下の通りです。 現在「15 型の継承について見ていこう」で躓いています。 01 オブジェクトを使ってみよう (02:56) 02 投稿に関する処理を作ろう 03 クラスでデータ型を定義しよう 04 インスタンスを作ってみよう 05 コンストラクタを使ってみよう 06 クラスを整理しておこう 07 アクセス修飾子について見ていこう 08 メソッドを介してプロパティを操作しよう 09 プロパティで型宣言をしてみよう 10 staticキーワードを使ってみよう 11 オブジェクト定数を使ってみよう 12 クラスを継承してみよう 13 子クラスで独自の実装をしていこう 14 メソッドをoverrideしてみよう 15 型の継承について見ていこう *型の継承 *型を継承するメリット この項目で記述されているソースコードは下記のとおりです。コード内のクラス、SponsoredPostは クラスPostを継承しています。よって両方のクラスともにPost型として扱えると説明があります。 ソース内のこの箇所で processPostという関数を作成し、変数$postにPost型と型付けをしています そしてforeachでPostで型付けられた$post型(クラスPostとそれを継承したクラスSponsoredPost)をひとつづつ取り出し、processPostを用いてそれぞれにshow()メソッドで表示させています。 ----------------------- <?php class Post{ protected $text; public function __construct($text){ $this->text = $text; } public function show(){ printf('%s',$this->text); } class SponsoredPost extends Post{ private $sponsor; public function __construct($text, $sponsor){ parent::__construct($text); $this->sponsor = $sponsor; } public function show(){ printf('%s by %s', $this->text, $this->sponsor); } } $posts = []; $posts[0] = new Post('hello'); $posts[1] = new Post('hello again'); $posts[2] = new SponsoredPost('iPhone','Apple'); function processPost(Post $post){ $post->show(); } foreach($posts as $post){ processPost($post); ------------- クラスを継承すると親クラスのプロパティやメソッドが子クラスに継承されるというのは理解できています。「15 型の継承について見ていこう」という項目では 『Post型の変数を受け取る関数を作って、データ型が継承されることを説明していきます。』 と解説してあります。 クラスを継承すると親クラスのプロパティやメソッドが子クラスに継承されるというのは理解できています。私の知っているデータ型(文字列型、整数型、浮動小数点数型、論理型、配列型、オブジェクト型、リソース型、NULL)は下記の2か所だけです。 show()メソッド内の、['%s']と['%s by %s']で文字列が指定されています。 したがってこの項目で説明されている 『Post型の変数を受け取る関数を作って、データ型が継承されることを説明していきます。』 とは、「クラスを継承する際にプロパティやメソッドだけでなく、データ型、ここでは(['%s']と['%s by %s'])も継承されるということが説明されているという解釈でよろしいのでしょうか? 少し混乱しています。もし私の解釈が間違っているようでしたら教えてください。 初学者です。よろしくお願いいたします。 <表示結果>

    • ベストアンサー
    • PHP
  • PHPのクラス継承において質問

    class SuperClass{ public function getSuperClassName (){ //操作中のオブジェクトのクラス名を取得する print get_class($this); print "<br />"; print __CLASS__; } } class SubClass extends SuperClass{ public function getSubClassName (){ //操作中のオブジェクトのクラス名を取得する print get_class($this); print "<br />"; print __CLASS__; } $obj = new SubClass(); print "<br />"; $obj -> getSuperClassName(); print "<br />"; $obj -> getSubClassName(); 上記のようなコードがあった場合、 出力結果は SubClass SuperClass //継承しているにもかかわらず、SuperClassという文字列が返る。 SubClass SubClass と上記のようになります この結果に一点疑問があるのですが、親クラスのメソッドは子クラスに継承されるんですよね? であれば親クラスの public function getSuperClassName (){ //操作中のオブジェクトのクラス名を取得する print get_class($this); print "<br />"; print __CLASS__; } の箇所の print __CLASS__; の記述箇所はSubClassとでなければいけないような気がします。 しかし結果はSuperClassとでますが、このメソッドは子クラスに継承されていないのですか? publicなら継承されるとマニュアルにかいてありましたが、どうなっているのでしょうか よろしくご教授御願い致します。

    • ベストアンサー
    • PHP
  • クラスを継承するか、変数に入れて持ち回すか?

    掲示板のような仕組みを作っています。 そこで、とりあえず先にHPのヘッダーをと思いPHPRequestというクラスを作りました ユーザーエージェントを元に、Doctypeや文字コード、アクセスしたディレクトリ情報が入っているものです これをヘッダーに継承させるか、変数に放り込んで掲示板の方にも使い回しするかで悩んでいます。 リクエスト class PHPRequest { function PHPRequest() { xxxxx } } ******************************** パターンA class PageHeader extends PHPRequest { } class BBS extends xxxxx { function BBS() { $request = new PHPRequest; } } ******************************** パターンB $request = new PHPRequest; class PageHeader { function PageHeader($request) { $this->xxxx=$request; } } class BBS extends xxxxx { function($request) { $this->xxxx = $request; } } どちらの使い方が正しいのでしょうか? 二通りのやり方をやってみましたけど、特段速度に差があるようにも思えないんです… クラスの考え方が基本的に間違えてるっていうことでしたら、間違えてると言ってくださった方がスッキリします どうも気になって先に進めないので教えてください! お願いします!

    • ベストアンサー
    • PHP
  • PHPでの継承について

    PHPの継承についての質問です。 PHPではクラスを継承する場合 スーパークラスのpublicとprotectedなメンバを継承すると いいます。 継承とは、スーパークラスで定義したメンバが サブクラスで定義されたことと同義である。 という前提で質問します。 ひょっとしたらこの前提も微妙に間違っているかもしれません。 以下の用なコードがあるとします。 <?php class AClass { //サブクラスへ継承されるスーパークラスのメソッド public function superClassPublicMethod(){ //【1】 $this-> subClassPrivateMethod(); } } class BClass extends AClass{ public function subClassPublicMethod(){//【2】 $this->subClassPrivateMethod(); } //継承したスーパークラスで定義されているメソッドからコールするサブクラスで定義したメソッド private function subClassPrivateMethod(){ //【3】 print __CLASS__; } } $obj = new BClass(); //サブクラスで定義した public なメソッドを実行 $obj->subClassPublicMethod(); //【4】 //スーパークラスから継承したpublic なメソッドを実行 $obj-> superClassPublicMethod();//【5】 ?> コレを実行すると【4】はきちんとBClassという結果が返ってきます。 ところがその下の【5】を実行すると Fatal error: Call to private method BClass::subClassPrivateMethod() from context 'AClass' in /usr/local/apache/htdocs/ext06.php on line 9 という実行時エラーが返ってきます。これを読むと、AClassのコンテキスト内ではBClassのprivateなメンバは コールできませんよ。というエラーですね。そもそもAClassのコンテキストということは、これはAClass内で実行されているということですよね? ここで、スーパークラスからこのpublicなメソッドは継承しているはずなのになぜ、サブクラスのBCLass内ではなくスーパークラスのAClass内という エラーが返っているのでしょうか? 継承とは、サブクラスで定義したと同義ではなく、スーパークラスまで内部的にアップキャスト?してコールしにいっているのでしょうか? 詳しい方ご教授ください。 よろしく御願いします。

    • ベストアンサー
    • PHP
  • 継承クラスで定義したメソッドのtry-catch文

    親クラスで、子クラスで実装されたメソッドのExceptionをキャッチしたいのですが、 うまくいきません。 何か良い方法はないでしょうか? abstract class A { public __construct(){ try{ $this->testA(); }catch(Exception $e){ var_dump(1); } } abstract function testA(); } class B extends A { function testA(){ throw Exception('test',1); } } try{ new B; }catch(Exception $e){ var_dump(2); // こっちが動く } よろしくお願いします。

    • ベストアンサー
    • PHP
  • equals()メソッドの継承について

    ある本に ーーーーーーーーーーーーーーーーーーーーー class Car { protected int num; protected double gas; public Car() { num = 0; gas = 0.0; System.out.println("車を作成しました。"); } } class Sample8 { public static void main(String[] args) { Car car1 = new Car(); Car car2 = new Car(); Car car3; car3 = car1; boolean bl1 = car1.equals(car2); boolean bl2 = car1.equals(car3); System.out.println("car1とcar2が同じか調べたところ" + bl1 + "でした。"); System.out.println("car1とcar3が同じか調べたところ" + bl2 + "でした。"); } } JavaのクラスはすべてObjectクラスのメンバを継承していますので、equals()メソッドを記述しなくても、このメソッドを呼び出すことが出来るわけです。 ----------------------------------------- JavaのクラスはすべてObjectクラスのメンバを継承していますので、equals()メソッドを記述しなくても、このメソッドを呼び出すことが出来る    についてですが、 逆から言えば他の言語の場合は本来クラスの宣言の辺りにでもequals()メソッドを記述する必要があるという意味なんでしょうか?

    • ベストアンサー
    • Java
  • 抽象クラスを継承した普通のクラスから、

    抽象クラスを継承した普通のクラスから、 抽象クラス内でprotected宣言したクラスのフィールド(連想配列)へ データをセット&ゲットしてみたいのですが、やり方がよく分かりません。 上記内容を満たす簡単なサンプルを誰か作っていただけないでしょうか。 ちなみに、下記は、自分でやろうとして、頭がこんがらがってしまった例です。 あくまでもイメージですが、 こんな感じで、作成していただけると、うれしいです。 <?php abstract class A1{ protected $data = array();   public function setData($value){ $this->data[$key] = $value; } public function getData($key = null){ if (null == $key) { $this->data; } else { $this->data[$key]; } } } class C1 extends A1{ public function main(){ $this->setData('key1') = 'value1'; $this->setData("キー2") = "値2"; } } $c1 = new C1; $c1 -> main(); var_dump($data); ?>

    • ベストアンサー
    • PHP
  • PHPでのstatic(静的)メソッド・メンバの継承について教えてください。

    次のような例にて、私の考えているように動作しません。 class ClassA {  protected static function method1()  {  echo "111";  }  public static function method2()  {  self::method1();  } } class ClassB extends ClassA {  protected static function method1()  {  echo "222";  } } ClassB::method2(); // ---> 111 と表示される。 ------ 私としては、222と表示されると予測していたのですが、 思ったように動作しません。 継承された子クラスClassBにて、method2() が実行され、 その中での self::method1(); のselfが、 ClassBではなく、親クラスのClassAを指し示していると思われます。 私としては、継承された子クラスでのselfは、相対的に、子クラスをあらわしてほしいのですが。 そういうものだ、と言われればそれまでなのですが、 これだと、self::method1(); でも、ClassA::method1(); でも同じことになってしまい、 selfの存在意義がないことになってしまうのでは?と思うのです。 私の理解のどこが間違っているのか教えていただけると幸いです。 どうぞよろしくお願いします。

    • 締切済み
    • PHP
  • 継承したクラスを、継承元のクラス型の引数に渡すとどうなるのでしょうか?

    継承したクラスを、継承元のクラス型の引数に渡すとどうなるのでしょうか? 以下のようなケースで、 #include "stdio.h" using namespace std; // baseクラス class base { private:  int m_nII;  int m_nJJ;  int m_nKK; public:  base(int i,int j,int k){ m_nII=i; m_nJJ=j; m_nKK=k; }  int GetSum(){ return (m_nII+m_nJJ+m_nKK); } }; // base 継承クラス class hoge : public base { public:  hoge() : base(1,2,3){} }; void func(base* obj){ // baseクラスを引数に取る関数  printf("sum is %d\n", obj->GetSum()); } // main int main(){  hoge objHoge;  func((base*)&objHoge); // <-キャストして渡す  return 0; } として、一応、gccでコンパイルは通り、実行結果も期待通りだったのですが、 このやり方で問題は無いのでしょうか? (たとえば継承先のクラスが独自のメンバを持っていたりなどした場合、期待した結果にならないとか・・) よろしくお願いします。

専門家に質問してみよう