プロが教えるわが家の防犯対策術!

C#2.0を使用しています。

MessageBoxを継承して拡張させたいと思い、MessageBoxExなるクラスで
次のように記述したのですが

public class MessageBoxEx : System.Windows.Forms.MessageBox
{
}

型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません。
というエラーが出てしまいます・・・

これはどういうことなのでしょうか?
コンストラクタが定義されてないクラスは継承できないのでしょうか?

A 回答 (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の意味も理解するよう努力をしてください。


そしてまた疑問点が出たらば、ココで諸先輩方に聞いてみましょう。
    • good
    • 0

私も精通するほど知識がないため推測めいたものになってしまいますが…



> 「型 '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の戻り以外使えない、という制約もありません。

この回答への補足

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

補足日時:2009/02/24 01:15
    • good
    • 0
この回答へのお礼

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

>『MessageBoxの継承』にとらわれすぎず、Formを継承し、まったく新しく「MyMessageBox」などを作ってみてはいかがでしょう?
自分もそのように作っているところす。
要はshowDialog()を呼び出せば同じことですよね。

お礼日時:2009/02/24 01:13

コンストラクタを指定しない場合、引数なしのコンストラクタがコンパイラにより定義されます。


また、基底クラスのコンストラクタを指定しない場合、基底クラスの同一引数を持つコンストラクタが指定されます。

class a{}
は、
class a{ public a(){} }
といっしょです。

class a (基底クラスを継承)のコンストラクタ定義は
a() : base() {}
といっしょです。


今回の場合、コンストラクタを指定しないので、MessageBox のコンストラクタ
private MessageBox()
が呼ばれたことになり、これが
「アクセスできない保護レベルになっています」
となるわけです。


継承できないクラスに追加挙動を与える場合は、
・アダプタパターン [Gamma95]
・デコレーターパターン [Gamma95]
があります。

調べてください。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/02/20 17:34

http://msdn.microsoft.com/ja-jp/library/system.w …
失礼、名前空間がこっちの方でしたね。sealed ではないですね。こちらは新しいインスタンスは作成できないものとなってます。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/02/19 17:29

http://msdn.microsoft.com/ja-jp/library/system.w …

public sealed class MessageBox

sealed だから継承不可なクラスです。
    • good
    • 0

Windowsプログラミングをやるなら(言語を問わず)、ヘルプやMSDNを検索する癖をつけましょうね。


http://msdn.microsoft.com/ja-jp/library/system.w …
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/02/19 16:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!