• 締切済み

MessageBoxを継承したい

C#2.0を使用しています。 MessageBoxを継承して拡張させたいと思い、MessageBoxExなるクラスで 次のように記述したのですが public class MessageBoxEx : System.Windows.Forms.MessageBox { } 型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません。 というエラーが出てしまいます・・・ これはどういうことなのでしょうか? コンストラクタが定義されてないクラスは継承できないのでしょうか?

みんなの回答

回答No.6

> 例えば、次のような継承元クラスaはコンストラクタが定義されてなくても > エラーは出ないでコンパイルが通ります。 > public class a > { ... } > public class b : a > { ... } これは、プログラムの中で、動的に(newして)使用しているクラスですよね? ということは、デフォルトコンストラクタが呼び出されていると思います。 この場合は、「何もしないで」オブジェクトを作成します。 (正確にいうと、「class a」はobject型を継承していますし、メモリの動的確保なども裏方でやってはいますが) 私は、Visual C# 2008 Express Editionで作業をしています。 もし可能なのであれば、Visual C# 2008 Express EditionをインストールしてWindowsApplicationのプロジェクトを起してください。 この場合、ソリューション エクスプローラに、「Program.cs」というファイルがあるはずです。 ここで重要なのは"static"です。 C#はオブジェクト指向開発言語なので、あらゆるものがオブジェクトです。 オブジェクトはnewキーワードで作成されます。 ところで、重要な問題があります。大小さまざまなオブジェクトで構成されたアプリケーションを、『どこか』でnewしないといけません。ではどこでnewすればいいのか… その結果が、「アプリケーションのエントリポイント」です。 アプリケーションを動かすためのアプリ…では同道廻りになるので、アプリケーションのエントリポイントのみを目的としたコードのあるファイルは、「Program.cs」です。 それと合わせて、staticの意味も理解するよう努力をしてください。 そしてまた疑問点が出たらば、ココで諸先輩方に聞いてみましょう。

回答No.5

私も精通するほど知識がないため推測めいたものになってしまいますが… > 「型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません」 > というエラーが出てしまうのでしょうか? 一番考えられるのは、本当にコンストラクタの定義が無い、だと思います。 「なんでそんな結論?」と問われるのであれば、MessageBoxを使用するとき、 MessageBox mb = new MessageBox(...); mb.Show(); とMessageBoxのインスタンスを作成していますか? MessageBox.Show(...); と、static メソッドを呼び出しているはずです。 > 考えられる理由としては.NET固有のクラスライブラリを使用(継承)する場合は > なんかエラーの内容が変わってしまうとかあるのでしょうか? 私はVisual C# 2008 Express Editionを使用していますが、コロコロとエラーの内容が変わっていたらば、作る側は困ります。 統合開発環境でウィンドウズアプリケーションを選ぶと「Form1」と、デザイナの上に表示される(と思いますが)、これは、.NET クラスライブラリの『Form』クラスを継承して作られています。 基本は同じです。 もし私が「SuperMessageBox」なんて言うものを作ろうとしたのであれば、その時々に合わせて、Formから継承させ、サイズの変更などを出来ないようにして、smb.showDialog(); させるでしょう。 そこでユーザーの選択で、DialogResultを返すつくりにすると思います。 『MessageBoxの継承』にとらわれすぎず、Formを継承し、まったく新しく「MyMessageBox」などを作ってみてはいかがでしょう? 画像が必要であれば、ネット上を探しまわればライセンスフリーの画像集などあると思います。 当然ですが、DialogResultはMessageBoxの戻り以外使えない、という制約もありません。

takagoo100
質問者

お礼

ご返答ありがとうございます。 >本当にコンストラクタの定義が無い、だと思います。 自分もそうだと思うのですが、 でも例えば、次のような継承元クラスaはコンストラクタが定義されてなくても エラーは出ないでコンパイルが通ります。 public class a { } public class b : a { } 仮にクラスaをクラスMessageBoxに置き換えたとしても 同じようなことだと思うのですが・・・ 一体どういう記述の仕方(クラス構造)なら 「コンストラクタが定義されていません」 というエラーを発生させることができるのでしょうか? >『MessageBoxの継承』にとらわれすぎず、Formを継承し、まったく新しく「MyMessageBox」などを作ってみてはいかがでしょう? 自分もそのように作っているところす。 要はshowDialog()を呼び出せば同じことですよね。

takagoo100
質問者

補足

訂正 自分もそのように作っているところす。 自分もそのように作っているところです。

  • Xaval
  • ベストアンサー率58% (61/105)
回答No.4

コンストラクタを指定しない場合、引数なしのコンストラクタがコンパイラにより定義されます。 また、基底クラスのコンストラクタを指定しない場合、基底クラスの同一引数を持つコンストラクタが指定されます。 class a{} は、 class a{ public a(){} } といっしょです。 class a (基底クラスを継承)のコンストラクタ定義は a() : base() {} といっしょです。 今回の場合、コンストラクタを指定しないので、MessageBox のコンストラクタ private MessageBox() が呼ばれたことになり、これが 「アクセスできない保護レベルになっています」 となるわけです。 継承できないクラスに追加挙動を与える場合は、 ・アダプタパターン [Gamma95] ・デコレーターパターン [Gamma95] があります。 調べてください。

takagoo100
質問者

お礼

ご返答ありがとうございます。 拡張についてはそのいずれかのパターンでやりたいと思います。 ただまだ1つ分からないことは、なぜSystem.Windows.Forms.MessageBoxを継承した場合に、 「アクセスできない保護レベルになっています」 ではなくて 「型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません」 というエラーが出てしまうのでしょうか? 考えられる理由としては.NET固有のクラスライブラリを使用(継承)する場合は なんかエラーの内容が変わってしまうとかあるのでしょうか?

  • pica_zip
  • ベストアンサー率67% (19/28)
回答No.3

http://msdn.microsoft.com/ja-jp/library/system.windows.forms.messagebox(VS.80).aspx 失礼、名前空間がこっちの方でしたね。sealed ではないですね。こちらは新しいインスタンスは作成できないものとなってます。

takagoo100
質問者

お礼

ご返答ありがとうございます。 >新しいインスタンスは作成できない 例えばこれは自分でそういうクラスを作成する場合、 どのように記述すれば作れるのでしょうか? コンストラクタにprivateなどを指定してみたりしたのですが public class a { private a() { } } public class b : a { } 'Test.a.a()' はアクセスできない保護レベルになっています。 というエラーで ~のコンストラクタが定義されていません。 というエラーにはならないのですが、 でも単にコンストラクタを定義しないクラスaではエラーなく継承できますし、 System.Windows.Forms.MessageBoxはどのような構造なのでしょうか?

  • pica_zip
  • ベストアンサー率67% (19/28)
回答No.2

http://msdn.microsoft.com/ja-jp/library/system.windows.messagebox(VS.80).aspx public sealed class MessageBox sealed だから継承不可なクラスです。

回答No.1

Windowsプログラミングをやるなら(言語を問わず)、ヘルプやMSDNを検索する癖をつけましょうね。 http://msdn.microsoft.com/ja-jp/library/system.windows.forms.messagebox.aspx

takagoo100
質問者

お礼

ご返答ありがとうございます。 すいません、自分も検索したつもりだったんですが どうやら.NET Framework 3.5の方を検索してたようです・・・ 直接VSの方からF1で検索すればよかったんでしょうけど、ネットから探してました・・・ 自分もsealedクラスなのかな?と思い、別の自作したsealedクラスで継承させてみたのですが、 それは、シール型からは派生させることができません、というエラーがでます。 型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません。 というエラーはどういうことなのでしょうか? 当然ですが試しに自分で作成したコンストラクタを定義してないクラスは継承できました。 System.Windows.Forms.MessageBox内ではどのように記述されているのでしょうか?

関連するQ&A

  • C++を勉強し始めたばかりの初心者なのですが、クラスの継承に関して・・・

    Visual C++ 2008で、新しいwindowsフォームアプリケーションを作成したら、Form1.hの上の方に public ref class Form1 : public System::Windows::Forms::Form という行がありました。これは開発環境に実装されている System::Windows::Forms::Formクラスを継承し、Form1クラスを新たに作成しますという意味なのですよね? このとき、2つ目のpublicは、継承の仕方、この場合結果的にはSystem::Windows::Forms::Formクラスに含まれるメンバの、private以外がそのまま受け継がれる、という事になりますよね? それで、このref classというのは、ポインタみたいな意味でしょうか?refは書かないと別の継承方法になるのでしょうか? また、最初のpublicはどういう意味なのでしょう? もしかして、この2つについては、System::Windows::Forms::Formクラスを継承して新規フォームを作る場合の、定型みたいなものなのでしょうか?

  • 継承における暗黙のデフォルトコンストラクター

    ”継承の際、スーパークラスで引数なしのコンストラクターが省略せずにきちんと記述されるなら、そのサブクラスでコンストラクターを記述しなくても、スーパークラスの引数なしのコンストラクターが受け継がれるためコンパイルエラーがおきない。”のは分かりますが”スーパークラスで引数なしのコンストラクターが省略され、かつサブクラスでコンストラクターを省略した場合”はなぜコンパイルエラーがおきるのでしょうか? 暗黙の内にスーパークラスにコンストラクターが生成され、それがサブクラスに受け継がれることは出来ないのでしょうか? 宜しく願います。

  • C#の継承関係。

    すこし、疑問におもい質問いたします。 以下のようなコードなのですが using System; using System.Windows.Forms; public class MainClass{ public static void Main (){ Test01 obj01 , obj02; Test02 obj03 , obj04; obj01= new Test01(); obj01.method01(); obj03 = new Test02(); obj03.method02(); try{ obj02 = (Test01)obj03;(1) //obj02.methodp();(2) obj04 = (Test02)obj01;(3) }catch(Exception e){ MessageBox.Show(e.Message); } } } public class Test01{ public void method01(){ MessageBox.Show("スーパークラスメソッド"); } private void methodp (){ MessageBox.Show("スーパークラスプライベートメソッド"); } } public class Test02 : Test01{ public void method02(){ MessageBox.Show("サブクラスメソッド"); } } まず(1)の箇所ですが、これはTest02というTest01のクラスを継承したサブクラスを Test01という親クラスにキャストしてます。 これは、問題なく動いているようです。 ただ、その下の(2)の箇所でキャストしたインスタンスから親クラスのプライベートメソッドにアクセスしようとしたらコンパイル時にエラーとなりました。 サブクラスを親クラスにしても親クラスのプライベートメソッドって使えないのでしょうか?であれば親クラスへのキャストって何のためにあるのでしょうか? 次に(3)の箇所ですが、これはTest01という親クラスをTest02という子クラスにキャストしようとしていますが、どうも、親クラスから子クラスへキャストできないといいう例外が 発生するようです。 これはなぜなのでしょうか? 以上の点でご教授いただけませんでしょうか? よろしくお願いします。

  • コンストラクタの記述について ―引数を持ったクラスを継承する場合―

    コンストラクタの記述について ―引数を持ったクラスを継承する場合― ActionScript3.0でプログラミングをしています。 クラスの継承に挑戦したのですが、うまくいきません。 コンストラクタの記述は、何か特別なものが必要なのでしょうか? ■コンストラクタに引数なし → 成功。 ■コンストラクタに引数あり → 失敗。  エラー「No default constructor found in base class <親クラスの名前>」。 ■エラーの出るソース↓ ・Main.as(コンストラクタ内抜粋)     var parent:Parent = new Parent(100);     var child:Child = new Child(200); ・Parent.as package {   import flash.display.Sprite;      public class Parent extends Sprite {     protected var str:String = "親クラスのプロパティ";     public function Parent(inNum:Number):void {       trace("親クラス, ", str, inNum);     }   } } ・Child.as package {   import Parent;   public class Child extends Parent {     public function Child(inNum:Number):void { //■エラー。       trace("子クラス, ", str, inNum);     }   } } ご存知の方、よろしくお願いします。 よろしくお願いします!

    • ベストアンサー
    • Flash
  • WebBrowserコントロールを継承するには

    VB.NETで既存のWebBrpwserコントロールを継承して 独自のコントロールを作成せいしたいのですが上手くいきません。 以下、私が実践した手順です。 1.プロジェクトにクラスを追加   →クラス名:CBrowser 2.CBrowserにWebBrowserを継承   →Inherits WebBrowserを記述 3.フォームに既存のWebBrowserを配置 4.Designer.vbを編集   →2箇所のSystem.Windows.Forms.WebBrowserをCBrowserに置き換え このやり方だと、稀にフォームデザイナーがエラーを出してしまいます。 よろしくお願いします。

  • 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
  • VC++.NET2003でユーザー関数内でMessageBox::Show()が使えません??

    VC++.NET 2003 のヘルプの、「チュートリアル : 簡単な Windows フォームの作成」に MessageBox::Show()関数を使ってHello,worldを表示させる例が書いていますが、 この関数を、自分で作った関数(フォームのクラスのメンバ関数で、 関数のコードはインライン関数でなく、cppファイル側に書いています)に持っていくと、 error C2653: 'MessageBoxA' : 識別子がクラス名でも名前空間名でもありません。 error C2660: 'System::Windows::Forms::Control::Show' : 関数に 1 個の引数を指定できません。 と、コンパイルエラーが出てしまいます。 MessageBox::Show()を自前の関数で使う方法を、 どなたか教えていただけないでしょうか?

  • WPF C# PointToClient

    お世話になります。 宜しくお願いいたします。 以下のコードでエラーが出ます。 System.Drawing.Point p = this.PointToClient(System.Windows.Forms.Cursor.Position); エラー内容 'クラス名' に 'PointToClient' の定義が含まれておらず、型 'クラス名' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。 使用中のクラスは、たしかに System.Windows.Controls.UserControl を継承しています。 さまざまな方法を試しましたが、全く理解できません。 ・解決方法または、WPFでマウス座標を取得する方法について ご教授お願いいたします。

  • 【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
  • 継承について

    みなさま、どうかお知恵を貸して下さい。 javaを勉強中で、本を読みながら試しに動かしています。 現在、実現したい動作が実現可能かどうかを調べているところです。 そのため、環境やバージョン等は決まっておりません。 むしろ、実現可能な環境やバージョンがあれば、教えてください。 実現したい機能ーーーーーーーーーーーー 親クラスAにメンバーとメソッドを定義します。 Aを継承する子クラスBを定義します。 プログラム中で、A、Bのインスタンスを生成します。 そして、A、Bを継承するCのインスタンスを生成したいのです。 Cのメンバーやメソッドは、Bと同様のものです。 この場合、BのクラスからCのようなインスタンスを作成することは、可能なのでしょうか? ・・・Cを定義していないので、おそらく不可能かと思います。 やはりこういった場合、Aを継承しているBを継承するCクラスを定義しておく必要があると考えています。 では、Cを継承するD,Dを継承するE・・・というように、いくつ必要になるかわからない場合、最大数分継承したクラスを用意すべきでしょうか。 なぜ、そうしたいかというと、組織図のようなものを作成したいのですが、組織図を構成する人数は、ユーザーの任意としたいのです。 継承したクラスを用いれば、そのまま組織図の体系を表現できる気がしました。 質問が大雑把になってしまい、申し訳ないのですが、お力を貸していただければ幸いです。

    • ベストアンサー
    • Java

専門家に質問してみよう