C#2.0を使用しています。
MessageBoxを継承して拡張させたいと思い、MessageBoxExなるクラスで
次のように記述したのですが
public class MessageBoxEx : System.Windows.Forms.MessageBox
{
}
型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません。
というエラーが出てしまいます・・・
これはどういうことなのでしょうか?
コンストラクタが定義されてないクラスは継承できないのでしょうか?
A 回答 (6件)
- 最新から表示
- 回答順に表示
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の戻り以外使えない、という制約もありません。
ご返答ありがとうございます。
>本当にコンストラクタの定義が無い、だと思います。
自分もそうだと思うのですが、
でも例えば、次のような継承元クラスaはコンストラクタが定義されてなくても
エラーは出ないでコンパイルが通ります。
public class a
{
}
public class b : a
{
}
仮にクラスaをクラスMessageBoxに置き換えたとしても
同じようなことだと思うのですが・・・
一体どういう記述の仕方(クラス構造)なら
「コンストラクタが定義されていません」
というエラーを発生させることができるのでしょうか?
>『MessageBoxの継承』にとらわれすぎず、Formを継承し、まったく新しく「MyMessageBox」などを作ってみてはいかがでしょう?
自分もそのように作っているところす。
要はshowDialog()を呼び出せば同じことですよね。
No.4
- 回答日時:
コンストラクタを指定しない場合、引数なしのコンストラクタがコンパイラにより定義されます。
また、基底クラスのコンストラクタを指定しない場合、基底クラスの同一引数を持つコンストラクタが指定されます。
class a{}
は、
class a{ public a(){} }
といっしょです。
class a (基底クラスを継承)のコンストラクタ定義は
a() : base() {}
といっしょです。
今回の場合、コンストラクタを指定しないので、MessageBox のコンストラクタ
private MessageBox()
が呼ばれたことになり、これが
「アクセスできない保護レベルになっています」
となるわけです。
継承できないクラスに追加挙動を与える場合は、
・アダプタパターン [Gamma95]
・デコレーターパターン [Gamma95]
があります。
調べてください。
ご返答ありがとうございます。
拡張についてはそのいずれかのパターンでやりたいと思います。
ただまだ1つ分からないことは、なぜSystem.Windows.Forms.MessageBoxを継承した場合に、
「アクセスできない保護レベルになっています」
ではなくて
「型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません」
というエラーが出てしまうのでしょうか?
考えられる理由としては.NET固有のクラスライブラリを使用(継承)する場合は
なんかエラーの内容が変わってしまうとかあるのでしょうか?
No.3
- 回答日時:
失礼、名前空間がこっちの方でしたね。sealed ではないですね。こちらは新しいインスタンスは作成できないものとなってます。
ご返答ありがとうございます。
>新しいインスタンスは作成できない
例えばこれは自分でそういうクラスを作成する場合、
どのように記述すれば作れるのでしょうか?
コンストラクタにprivateなどを指定してみたりしたのですが
public class a
{
private a()
{
}
}
public class b : a
{
}
'Test.a.a()' はアクセスできない保護レベルになっています。
というエラーで
~のコンストラクタが定義されていません。
というエラーにはならないのですが、
でも単にコンストラクタを定義しないクラスaではエラーなく継承できますし、
System.Windows.Forms.MessageBoxはどのような構造なのでしょうか?
No.2
- 回答日時:
public sealed class MessageBox
sealed だから継承不可なクラスです。
No.1
- 回答日時:
Windowsプログラミングをやるなら(言語を問わず)、ヘルプやMSDNを検索する癖をつけましょうね。
http://msdn.microsoft.com/ja-jp/library/system.w …
ご返答ありがとうございます。
すいません、自分も検索したつもりだったんですが
どうやら.NET Framework 3.5の方を検索してたようです・・・
直接VSの方からF1で検索すればよかったんでしょうけど、ネットから探してました・・・
自分もsealedクラスなのかな?と思い、別の自作したsealedクラスで継承させてみたのですが、
それは、シール型からは派生させることができません、というエラーがでます。
型 'System.Windows.Forms.MessageBox' のコンストラクタが定義されていません。
というエラーはどういうことなのでしょうか?
当然ですが試しに自分で作成したコンストラクタを定義してないクラスは継承できました。
System.Windows.Forms.MessageBox内ではどのように記述されているのでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C# 継承の問題で programに示された拡張をすべて含んだ上で,クラス Mammal に,そのオ 1 2022/07/22 09:48
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- C言語・C++・C# VisualStudioのソースコードで漢字を使いたい 4 2022/05/21 10:16
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- 弁護士・行政書士・司法書士・社会保険労務士 管理費滞納債務の特定承継人への承継 6 2022/04/02 16:59
- Windows 10 OSドライブのセキュアワイプ 2 2023/01/24 23:49
- C言語・C++・C# PC画面を録画するプログラムでdllの読み込みエラー 1 2023/04/22 08:31
- 相続・遺言 元配偶者の子の相続権について 3 2022/07/27 20:39
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FriendとPublicの違い。。。
-
クラスのアドレスを引数として...
-
イベントにAddHandlerされてい...
-
既定のコンストラクタがない?
-
C++では構造体がメンバ関数をも...
-
このコンパイルエラーの意味に...
-
(UWSC) 「#32770」の意味わかり...
-
スプラッシュコントロールの挿...
-
IncludeではなくClassで宣言す...
-
WindowsAPIのリストビューの...
-
form1 から form2 へのデータの...
-
ボタンのオーナードローについて
-
ウィンドウの背景に画像を配置する
-
コンソールアプリでのクリップ...
-
MFCアプリのコマンドラインでパ...
-
VC6 コンパイルエラー C2248に...
-
MessageBoxを継承したい
-
C++/CLIからC++の呼び出しで例外
-
個々の関数について継承してい...
-
VB2008: 継承の場合のコンスト...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
(UWSC) 「#32770」の意味わかり...
-
クラスのアドレスを引数として...
-
ダイアログ表示時にチェックボ...
-
イベントにAddHandlerされてい...
-
【ASP.NET】 独自で作成したク...
-
MFCアプリのコマンドラインでパ...
-
DebugクラスとTraceクラスの違い
-
ボタンのオーナードローについて
-
OnInitDialog()の関数の組み込み方
-
IncludeではなくClassで宣言す...
-
関数の呼び出し元の検索
-
このコンパイルエラーの意味に...
-
C++ protectedにアクセス不可
-
C++で継承元のクラスの代入演算...
-
DataGridViewのセルに斜線を引...
-
C#で通常のbuttonコントロール...
-
エディットコントロールのイベ...
-
CMainFrameクラスの使い方
おすすめ情報