質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

5回答

8182閲覧

C# Windows Formを多重継承したい

piglet

総合スコア47

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/09/13 05:00

こんにちは
現在、コードの保守性を上げる作業をしています。

例えばForm1とForm2で同じ機能のメソッドをいくつか持っている場合
これを共通化して一本にまとめたいのですが良い方法はないでしょうか?

共通のメソッドをまとめてクラス化し、Form1とForm2に継承させれば
綺麗に実装できるのでは?
と思ったのですがC#のFormは既にSystem.Windows.Formを
継承しているためできませんでした。

次善の方法として、Form1とForm2に同じ名前のサブクラスを作り
そいつに共通メソッドまとめたクラスを継承させればいいかなと思ったのですが
メソッドを呼び出す時に、頭にサブクラスの名前が付くのが何となく気持ち悪いです。
例: this.method() → subClass.method()

どのようにするのが最善なのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

System.Windows.Formを継承している親クラスを作って、そのclassをForm1とForm2に継承させれば良いのでは?

継承元

c#

1using System.Windows.Forms; 2 3namespace WindowsFormsApplication1 4{ 5 public partial class baseForm : Form 6 { 7 //作りたい処理 8 } 9}

継承先

C#

1 2namespace WindowsFormsApplication1 3{ 4 /// <summary> 5 /// テスト用フォームです 6 /// </summary> 7 public partial class Form1 : baseForm //こんな感じで 8 { 9

投稿2017/09/13 05:06

編集2017/09/13 05:08
motuo

総合スコア3027

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piglet

2017/09/13 08:18

これかな と思ったんですが よく見ると共通する処理が、Form1と「Form2に張り付けてあるUserControl内」にありました 一体どうすればいいんでしょう(´・ω・`)
motuo

2017/09/13 08:37

とすると、Formを継承するのはおかしいですね。別クラスにメソッドを切り出すのが良いと思いますが。
Tak1wa

2017/09/14 01:00

共通のUserControlのみBaseFormに張り付ければ良いのでは
guest

0

それは多重継承じゃなくても
Formを継承したFormAをさらにForm1,2がそれぞれ継承すればいいです。

System.Windows.Form <|-- FormA <|-- Form1 (,Form2)

ですが、「内部で同じようなコードが出てくるからまとめたい」という動機だったら、
継承より移譲のほうがいいと思います。

外部で同じようなコードが出てくる:
Form1のインスタンスもForm2のインスタンスも
FormA型として扱いたい場合がある、
つまり、FormA型の変数に入れたりメソッドの引数にしたい場合だったら、継承のほうがいいです。

投稿2017/09/13 08:18

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piglet

2017/09/13 19:35

デリゲートですね なんかピーンと来たんですが具体的な処理が思いつきませんでした(´・ω・`) ちょっと調べてみます。もし良い参考例とか文献がありましたら教えてくださると助かります。
ozwk

2017/09/13 22:20

ここで言う移譲は言語機能のdelegateじゃなくて 別のクラスに括ってそいつにお願いするって事です
guest

0

例えばForm1とForm2で同じ機能のメソッドをいくつか持っている場合これを共通化して一本にまとめたいのですが良い方法はないでしょうか?

意味が理解できません。

Visual Studio の「新しい項目の追加」で「Windows フォーム」を選択して追加していくと、Form を継承したクラスが Form1, Form2 ... と自動生成されていきますが、質問者さんの言う「Form1とForm2」はそのことを言っているのですよね?

で、Form1 と Form2 を多重継承して、たとえば Form3 を作りたいが、C# では多重継承ができないので困っていると言ってます?

多重継承する目的が分からないのですが、できないものは何ともならないので、普通に Form を継承した Form3 を作って、それに Form1 と Form2 にあるメソッドを重複しないよう自力でコードを書いて実装するという方法ではダメなのですか?

投稿2017/09/13 05:16

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piglet

2017/09/13 05:33

質問が悪かったみたいです(´・ω・`) Form1とForm2を作ったのですが、結果的に同じ処理をするメソッド(複数)を両者に作ってしまっていた 同じコードを二ヵ所に書くと後々両方を修正する必要があるので、一ヵ所にまとめたい だけど、別のクラスに纏めた場合、どうやってForm1とForm2から呼び出せばいいのだろう   → これらのメソッドを集めたクラスを継承させれば綺麗に実装できるのでは → 駄目だった じゃぁ、ユーティリティクラス(staticな共通の処理のメソッドを集めたクラス)でどうだろう   → なにか違う。オブジェクト指向的なもっといい方法はないのだろうか? ←いまここ こんな感じです。
退会済みユーザー

退会済みユーザー

2017/09/13 07:34

以下のような感じ(あくまで感じ、例です)なのでしょうか? (1) DB にアクセスしてデータを表示・編集する Windows Forms アプリを作っている。 (2) UI として Form1 と Form2 を作った。 (3) DB にアクセスしてデータを取得したり編集したりするコードを Form1 と From2 の両方に実装した。 (4) 完成した Form1 と Form2 のコードを眺めてみると同じ操作をしているコードが実装されている。 (5) それらを一か所にまとめたい。 であれば、プレゼンテーション層(UI を提供する Form)、ビジネスロジック層(From と DB をつなぐ)、データベース層の 3 層構造にし、上記 (3) のコードをビジネスロジック層に実装するというのが普通のやり方だと思います。 質問者さんのアプリがどういうものか分かりませんが、DB を扱うものではなくても、上に述べたような構造にはできるのではないでしょうか?
退会済みユーザー

退会済みユーザー

2017/09/13 07:39

上の私のコメントの、DB にアクセスしてデータを表示・編集する 3 層構造のアプリの具体例を紹介しておきます。 Windows Forms アプリの場合は、ビジネスロジック層には Visual Studio のデータソース構成ウィザードを利用して型付 DataSet + TableAdapter を作って使うのがよく行われる方法です。 具体的には、DB が SQL Server の場合ですが、以下のチュートリアル、 チュートリアル : データベースへのデータの保存 (単一テーブル) https://msdn.microsoft.com/ja-jp/library/0f92s97z(v=vs.120).aspx 10 行でズバリ !! 非接続型のデータ アクセス (ADO.NET) (C#) https://code.msdn.microsoft.com/windowsdesktop/10-ADONET-C-cbfe7688 ・・・のように Visual Studio のデータソース構成ウィザードを利用して型付 DataSet + TableAdapter を作って、それを利用してアプリを作ると、以下のページの図のような構造のアプリが、ほとんど自分でコードを書くこと無しに作れます。 Windows フォーム アプリケーションでのデータへの接続 https://msdn.microsoft.com/ja-jp/library/wxt2cwcc(v=vs.120).aspx
piglet

2017/09/13 19:39 編集

質問の意図が伝わってよかったです。 作っているのはDBとは違うのですが、フォーム+コントロール+データアクセスという構造は同じです なので今後も考えると三層アーキテクチャはありかもしれませんね
退会済みユーザー

退会済みユーザー

2017/09/14 00:58

お互い何か勘違いがないでしょうか? あるクラスの機能・メソッドを使うにはそのクラスを継承しないと使えないような実装になっている(メソッドに protected 修飾子が付いているとか)という話ではないですよね。 単に何らかの機能を実現するメソッドをまとめて共通に使いたいという話なら、ozawk さんが言われるように「別のクラスに括ってそいつにお願いする」ということを考えればいいはずです。 例えば文字列を操作したい場合、String クラスに実装されているメソッド等を探して、使えるものがあればそれを使いますよね? 質問者さんが独自に必要な機能を実装したクラスライブラリを作れば同じことができるのでは?
guest

0

こんにちは。

System.Windows.Forms.Form <- MyProject.Form MyProject.Form <- MyProject.Form1 MyProject.Form <- MyProject.Form2

でいいのでは?

投稿2017/09/13 05:05

tamoto

総合スコア4103

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piglet

2017/09/13 05:36

すいません。 "<-" これの意味がわかりませんでした(´・ω・`) 継承関係を示すのでしょうか?
tamoto

2017/09/13 05:42

そうです、わかりづらい書き方をしてしまいました…… motuoさんの回答が同じことを丁寧に説明しているのでそちらを参考にするのが良いと思います。
guest

0

自己解決

データを習得するクラスを継承して
重複していた操作メソッドで拡張することでとりあえずは上手くできました。
結果的に、フォーム → コントロール(操作)→ データの操作 という手順になり
一応は、MVCの三層アーキテクチャになったみたいです

VとCが1クラスになっちゃってますが・・・

*追記
まだ勉強不足で理解が足りないみたいなんでオブジェクト指向とかソフトウェア工学あたりを勉強してみます。
回答してくださった皆さんありがとうございました。

投稿2017/09/14 01:01

編集2017/09/14 01:16
piglet

総合スコア47

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問