c# 基本クラスの空っぽのプロパティ

このQ&Aのポイント
  • c#初心者のための基本クラスのプロパティについての質問です。
  • 基本クラスには、値を設定しても何も起らないプロパティが存在することがあります。
  • 継承先で実装されるが、基本クラスでは抽象になっていないプロパティについて、初心者は使うべきではないのか疑問です。
回答を見る
  • ベストアンサー

c# 基本クラスの空っぽのプロパティ

 こんにちは。c#初心者です。  今回はクラス設計についての質問です。  基本クラスの機能などが大きいものの中には、Controlクラスのように、「仮想プロパティとして存在するが、値を設定しても何も起らない」というものが混ざっています。  例えば、「AutoSize」プロパティです。ちゃんとインテリセンス(オートコンプリート)には表示されず、ツールチップでは「このクラスでは、このプロパティは使用されません」という文章は表示されます。  こういった「継承先で実装されるが、基本クラスでは抽象になっていないもの」は、好ましくないものなのでしょうか? 多用すべきではないのは当然だと思うのですが、使っていいのか、初心者は止めたほうがいいのか良く分かりません。  どなたか分かる方がいらっしゃいましたら教えていただけませんか?

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

  • ベストアンサー
  • kekyo0
  • ベストアンサー率62% (5/8)
回答No.1

非常に難しい問題だと思います。 まず、定義されているのに使用されないプロパティやメソッドは、その仕様を知らない使用者にとっては、意外な結果をもたらす可能性があります。 プログラム全体が十分安定的になって(もうコードを改良することもないほど練られている)も、まだこのようなメンバ定義が残っている場合、全体的な構造に欠陥がある可能性があります。 #アジャイルソフトウェア開発では、しばしは「不吉な匂い」と表現されます。 しかし、そうだとしても定義されていなければならない場合もあります。Controlクラスの場合、Controlクラス自身は全く意味をなしていないメンバですが、これを継承した様々なコントロールクラスは、オーバーライドして意味を持っている事が多くなります。 これが多数(つまり、Control自身は無意味な実装だが、派生クラスのほとんどには何らかの意味付けがされている)の場合は、不吉な匂いがするからといって、このような定義を排除するのは難しいでしょう。 もし、Controlクラスを自分が実装しているとして: よりベターなステップとして、まずこのようなメンバはインターフェイス定義に逃がすことが考えられます。AutoSizeプロパティを、ISizeableControlインターフェイスに定義し、これを実装するようにします。当然、Controlクラスには無意味なので、Controlクラスには実装しません。サイズ変更が意味を持つクラスにのみ実装するようにします。 「自動的にサイズ変更可能にするかどうかをチェックボックスで設定させる」フォームを作ったとします。このフォームのコンストラクタに、ISizableControlを渡すことで、フォーム内部でAutoSizeプロパティを制御できるようにします。すると、サイズ変更できるコントロールだけが、このフォームで制御可能になります。無関係なControlクラスを渡す事は出来ません。 更には、Controlを継承しているかどうかに関係なく、どのようなクラスでもISizableControlを実装していれば、フォームで同じように制御出来るようになります。 別の方法としては、コントロールのサイズ変更処理をControlクラス(とその派生クラス)内で行うのではなく、別のクラスで受け持つようにします。実際のSystem.Windows.Forms.Controlクラスではうまく説明できませんが、ウインドウメッセージを別の新しく作ったクラス、例えばSizeControllerクラスに転送(メソッド呼び出しなどで)し、そこでサイズ変更に関するさまざまな処理を行うというものです。これを「処理の委譲」と呼びます。 処理を委譲すれば、AutoSizeプロパティはSizeControllerクラスに移動できます。あとはどのようにSizeControllerクラスを実際のクラス(Controlを継承したクラス)に渡すか、という事だけを考えれば済みます。AutoSize以外にも、サイズ変更に関する様々なプロパティやメソッドは、SizeControllerクラスに定義すればよく、Controlクラスが不必要に膨れ上がることを防ぐことが出来ます。 #なお、現実のSystem.Windows.Forms.Controlクラスは、上記のような基本的な設計以外にも、単に「理解しやすい」(これも重要な要素)、デザイン時編集機能のサポートの問題などがあって、あのようになっているのではないかと推測しています。 #特にインターフェイス分離や委譲が多くなると、全体として何をするのかが分かりにくくなるというデメリットがあります。拡張性の高さ・保守の容易性・テスト容易性などとのトレードオフです。

koumei000
質問者

お礼

 なるほど、なかなか大変だということは分かりました。  初心者にはまだ手をつけないで何とかする方法を探したほうがいいような気がするので、今回は別の方法で何とかしてみます。  回答ありがとうございました。

関連するQ&A

  • 抽象クラスが継承されているかどうか検証したい

    Class.forName()にて取得したクラスが、特定の抽象クラスを継承しているかどうかを 検証したいです。 Class.getInterfaces()にて、実装されているインターフェースを取得することが出来ましたが、 Class.getClasses()、Class.getDeclareClasses()のいずれでも、継承されている 抽象クラスを取得することが出来ません。 そもそも抽象クラスはインスタンス化できないからなのかもしれませんが、 ならば、その抽象クラス名称を取得したいです。 方法はありますでしょうか? 無理ならばインターフェースの実装にし、基盤部で動作のカバーを する作りで考え直すつもりです。

    • ベストアンサー
    • Java
  • C++で参照カウンタを実装したいのですが

    こんにちは。 C++でクラスに参照カウンタを実装したいのですが、もしも実装する場合、 class CRefCounter {   参照カウンタとAddRef、Releaseメソッドを仮想メソッドとして実装 }; このクラスを継承して直接使う方法と、 class IRefCounter {   参照カウンタとAddRef、Releaseメソッドを純粋仮想メソッドとして宣言 } このクラスを継承して継承側で実装する方法とがあると思うのですが普通はどちらを使うものでしょうか?

  • JAVA:抽象クラスとインタフェースクラスの違い

    インタフェースクラスの存在意義がわかりません。 「処理の実体まで実装せず、箱だけ作っておく」という意味では、抽象クラスで良いのでは?と感じます。 (厳密には、インタフェースクラスの方は、継承せずに、複数の実装パターンを分けれるという部分に違いはあると思いますが、ほぼ存在意義がないように感じます。)

    • ベストアンサー
    • Java
  • C++のクラスの仮想デストラクタについて

    C++のクラスの仮想デストラクタについて教えてください。 デストラクタは、クラスの名前の前にチルダを付けたものが名前になりますが、とあるクラスの継承クラスは、その親クラスとクラス名が違うので、デストラクタの名前も親クラスのものとは別になる。つまり。継承関係のあるクラスでもデストラクタはオーバーライドせず、各クラス毎に別の名前で存在する、ということになると思います。 ですので http://wisdom.sakura.ne.jp/programming/cpp/cpp31.html このページの下部にあるように、「デストラクタは、派生クラスから基本クラスへ向かって順番に呼び出される」というのもなんとなく合点が行きます。 しかし、仮想デストラクタというものがあることを知りました。 上記のようにデストラクタは継承関係のあるクラス間でも、それぞれクラス毎に作ればよいと思っていましたが、子クラスの方でオーバーライドする必要がある場合があるのでしょうか。あるとすれば、それはどんな場合なのでしょうか。 また、上記のURLでは、「C++ 言語のデストラクタはオーバーライドを行いません」と書いてあり、なんだかよく分からなくなってきました。仮想デストラクタというものが存在するのに? どなたか詳しい方いらっしゃいましたらご教示頂けると幸いです。

  • C#でインターフェースのプロパティのアクセス修飾子

    お世話になります。 C#でインターフェースに定義した抽象プロパティで、アクセシビリティまで設定したいです。 例として抽象プロパティHelloのgetをpublic、setをinternalに設定したい場合、次の様に書くと怒られます。 string Hello { get; internal set; } ←"アクセシビリティ修飾子をインターフェイスのアクセサーで使用することはできません。" 抽象プロパティにsetを定義せず、サブクラスでinternalを設定して実装する分には怒られませんが、 この場合はサブクラスに対してsetの実装を強制できませんし、 当然API(インターフェース)型変数からsetの実装を呼び出せません。 全てのクラスはAPIからのみ利用させたいと考えていて、 かつプロパティのset、getで設定したいアクセス修飾子が異なる様な場合、 プロパティを使用せず自前でアクセッサを作るしか無いのでしょうか? 何かおいしい逃げ方がありましたらご教示いただけるとありがたいです。 宜しくお願いします。

  • VBA クラスにプロパティが実装できません

    VBA初心者です。 現在、Excel2003-VBAでクラスにプロパティの実装を試みていますが、うまくいきません。 Publicで宣言する方法は問題なく出来たのですが…。 勉強用のため、敢えて簡単なサンプルを自分で作っています。 【状況】 下記プログラムで、メッセージを「20」と表示させたいのですが、 「スタック領域が不足しています」エラーにより、実行できません。 また「Atai」を「Suji」にかえると、メッセージとして「0」と出てきます。 あるいは、「Suji = Atai + 5」を消してみても「15」ではなく「0」と出ます。 【質問】 どちらでもうまくいかないのですが、これは (1)このコードがおかしいのか、それとも (2)単純なプログラムであるのに領域不足と出るところから、 VBA特有の不具合でどうしようもない物なのでしょうか? ご意見お待ちしています。 ===通常Module(呼び出し側)=== Option Explicit Sub 実行() Dim Haichi As New Class1 With Haichi .Suji = 15 .MSGクラス End With End Sub ===クラスMODULE(Class1)=== Option Explicit Sub MSGクラス() MsgBox Suji End Sub Public Property Let Suji(Atai As Double) Suji = Atai + 5 End Property Public Property Get Suji() As Double End Property

  • 【C++】継承しながら、インプリメント。

    VB.netでは、以下のように継承しつつ実装ができると思いますが、 (1)C++ では、できないのでしょうか? (2)Java では、できないのでしょうか? Class SampleClass Inherits BaseClassHoge Implements InterfaceFoo また、 Implements は、Javaでは可能ではありますが、 C++ には「Implements」はないのでしょうか? (C++ では純粋仮想関数の集合となるアブストラクトクラスを継承するという方法しかできないのでしょうか?) .

  • インタフェイス実装と抽象クラス継承を同時に使うには??

    私はjava初心者です、今練習問題で困っています。 1つのクラスに抽象クラスとインターフェイスを 実装することはできるのでしょうか? 例えば abstract class Car { private String gas; public void getGas(int gas) { this.gas = gas; } public abstract void enjin(); } interface Flying extends Pet { void show(); } 上のインタフェイスと抽象クラスを同時に下のクラスに継承、実装しよう とすると、どんな風にかけば良いのでしょうか class Zoon { public Zoon() { super(); } public void enjin() { System.out.println("どどどどど"); } public void show() { System.out.println("いいくるまだ"); } }

    • ベストアンサー
    • Java
  • c# msdnや入力の際脇に出てくる記号

    c#、VisualStudioの使い方がだんだんわかってきました。 そこで気になったのですがインテリセンスなどが出たときプロパティやクラスを表すレンチなどの記号一覧はありますか? レンチのマークはプロパティだとわかるのですがクラスや構造体やメソッドなどは似たようなマークで一覧で紹介されているサイトなどないでしょうか? ネットではすぐに出てきませんでした。

  • 抽象クラスの継承について

    すいませんがご教授下さい。 ASP.NETとVB.NETを使用してアプリを開発しています。 存在するクラスは以下のようなクラスです。 (WebForm1.aspxとWebForm1.aspx.vbとClass1.vb(抽象クラス)があります。) したい事はClass1.vbをWebForm1.aspx.vbが継承したいのですが継承させた後にWebForm1.aspxを開こうとすると「Webフォームデザイナにファイルを読み込めませんでした。・・・・」とエラーポップアップが表示されます。「はい」でHTMLは見れるのですがデザインはタブ自体がないです。普通のクラスを継承させると問題ないのですが。抽象クラスだとエラーになります。 対処方を教えて下さい。