2011-02-04 2 views
0

これは基本的な考え方です。基本クラスはAnimalで、派生クラスはBirdとDogです。私はユーザーがどの動物を作成したいかを選択するためのComboBoxを持っています。フォームレベル(frmAnimal.cs - パブリック部分クラスfrmAnimal:フォーム)に、これらのすべてを組み込んで接続するにはどうすればいいですか?ユーザーが3つのオブジェクトタイプを選択できるようにするWindows Interface Formを作成するにはどうすればよいですか?

この決定に応じて、オーバーライドされたAnimalメソッドである.Move()を呼び出すボタンなど、フォーム上の他のボタンにも影響します。これは、BirdまたはDogオブジェクトタイプとして選択されます。

それは意味がありますか?

+0

私があなたの質問を理解している限り、多形性はすでにあなたのためにこれを処理します。特定の派生クラスをインスタンス化するだけです。オーバーライドされているかどうかに関係なく、自動的に 'Move'メソッドが呼び出されます。 –

+1

この質問は非常に一般的であいまいなので、答えることは難しいです。これまでのところあなたの努力とあなたが苦労している特定の分野を掲示する価値があります。 –

+0

右、Cody、私は、ボタンとコンボボックスを使って多態性をユーザーのやりとりに組み込む方法を主に考えています。 – Jordan

答えて

0

選択フォームとは別の新しいフォームを作成して表示しますか?もしそうなら、あなたは動物の種類のオブジェクトに制限され、フォームのクラスは、一般的な作ることができます:

public abstract partial class AnimalFormBase<T>:Form where T:Animal {...} 

あなたはその後、動物の具体的な形を作成するためにそのフォームから派生することができます:あなたがしたい場合

public partial class AnimalForm:AnimalFormBase<Animal> {...} 
public partial class BirdForm:AnimalFormBase<Bird> {...} 
public partial class DogForm:AnimalFormBase<Dog> {...} 

を私は上記のクラスをUserControlから派生させるでしょう。次に、ユーザーがラジオボタンを変更したときに、古い動物タイプのコントロールを削除して新しい動物のコントロールに置き換えることができました。どちらの方法でも、汎用祖先のAnimalFormBaseは、任意のAnimalに関する機能を保持できます。それは技術的にコントロールを含むことができますが、デザイナレンダリングされたクラスのカスタム継承が乱雑になることがわかりました。次に、3つの派生フォームは基本機能を使用し、独自の機能を追加し、それぞれがユーザーに提示するコントロールをレイアウトすることができます。

+0

私はフォームの基本的なものを考えています。フォームは全体の時間と同じになります。そのため、Moveボタンをクリックすると、ComboBoxでどのオブジェクトが選択されているかに応じて、BirdまたはDogまたはAnimal's Moveメソッドが使用されます。 – Jordan

+0

まあ、3つすべてがAnimalsなので、ラジオボタンが変更されたときに正しいタイプに再インスタンス化される(またはそのタイプの既存のオブジェクトのキャッシュから引き出される)Animal型のプロパティを持つことができます。プロパティのMove()メソッドを呼び出します。そのボタンは、プロパティの実際のタイプが何であっても気にしません。それはMoveメソッド(Animalから利用可能でなければならない)を持っていたことを知るのに十分なことを知っていました。 – KeithS

0

私の例はvb.netです(私はC#の学習に取り組んでいますが、まだ "そこ"ではありません - 違いはそれほど大きくないので意味がありません)。ユニバーサル失敗あなたは基本クラスのAnimalと、動物から派生したいくつかのクラスを持っています。ベースクラスの.Moveメソッドを定義します。次に、派生クラスを作成します。派生クラスは、基本クラスのメソッドとパブリック・インターフェースを継承します。動物の型を区別するために、AnimalTypeプロパティを定義します。この非常に単純な例では、私はEnumを使いました。実際には、これはEnumであるか、データベースPK、または他の一意の識別子である可能性があります。実際には、おそらくsuperType Animalを派生クラスと同じ列挙体のメンバーにしないことに注意してください。

Public Enum AnimalTypes 
    Animal = 1 
    Pig = 2 
    Human = 3 
End Enum 

Public Class AnimalBase 

    Public Overridable ReadOnly Property AnimalType() As AnimalTypes 
     Get 
      Return AnimalTypes.Animal 
     End Get 
    End Property 

    Public Sub Move(ByVal X As Integer, ByVal Y As Integer) 
     ' . . . You movement code 
    End Sub 
End Class 

今、あなたの派生クラス:

Public Class Pig 
    Inherits AnimalBase 

    Public Overrides ReadOnly Property AnimalType() As AnimalTypes 
     Get 
      Return AnimalTypes.Pig 
     End Get 
    End Property 

    'A property spcific to the pig class: 
    Public ReadOnly Property PigOnEquality() As String 
     Get 
      Return "Some pigs are more equal!" 
     End Get 
    End Property 
End Class 

Public Class Human 
    Inherits AnimalBase 

    Public Overrides ReadOnly Property AnimalType() As AnimalTypes 
     Get 
      Return AnimalTypes.Human 
     End Get 
    End Property 

    'A property specific to the Human class: 
    Public ReadOnly Property Shotgun() As String 
     Get 
      Return "Boom!" 
     End Get 
    End Property 
End Class 

、AnimalFactoryデータベースに私はおそらく例えば「親」動物レコード、)に関連する派生したオブジェクトの「子」レコードを作成します動物および型動物から派生したクラスのインスタンスをクランククラス、(1より多くの時間型動物。。。):

Public Class AnimalFactory 

    Public Shared Function NewAnimal(ByVal AnimalType As AnimalTypes) As AnimalBase 
     Select Case AnimalType 
      Case AnimalTypes.Animal 
       Return New AnimalBase 
      Case AnimalTypes.Pig 
       Return New Pig 
      Case AnimalTypes.Human 
       Return New Human 
      Case Else 
       Return New AnimalBase 
     End Select 
    End Function 

End Class 

ここでのトリックはreturneとして、派生クラスということですdはAnimalFacortyであり、動物型であるが、実際の型のすべてのプロパティを実装し、必要に応じてその真の型にキャストすることができる。さて、あなたのフォーム。基本クラスで定義されている一般的なメソッドにしかアクセスしていない場合は、フォームで返される動物の種類を必ずしも気にする必要はありません。派生クラス固有のメソッドにアクセスする必要がある場合は、VB.netと同じ(または非常に似ている)キャスト操作を実行する必要があります。

私は本当に愚かなこの形式の例Select Case(Switch文として知っていると思います)を避ける方法もありますが、コードで何をやっているのかわからないので、これは単純に練習問題です。 。 。

Public Class AnimalFarm ' My hilarious name for the FORM 

    'Member variable for the currently selected instance of AnimalBase 
    Private SelectedAnimal As AnimalBase 

    Private Sub AnimalFarm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load 

     'Using the enum to populate the comboBox: 
     With Me.ComboBox1.Items 
      .Add(AnimalTypes.Animal) 
      .Add(AnimalTypes.Pig) 
      .Add(AnimalTypes.Human) 
     End With 

    End Sub 

    Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged 
     Dim AnimalType As AnimalTypes = Me.ComboBox1.SelectedItem 
     Me.OnNewAnimalSelected(AnimalType) 
    End Sub 

    Private Sub OnNewAnimalSelected(ByVal AnimalType As AnimalTypes) 
     SelectedAnimal = AnimalFactory.NewAnimal(AnimalType) 

     'The form doesn't case what type of animal is being instantiated, so long 
     'as the methods required are defined on the base class: 
     MsgBox(SelectedAnimal.AnimalType.ToString) 

     'Move the animal a bit, just for kicks: 
     SelectedAnimal.Move(NewX, NewY) 

     ' . . . But if you NEED the specific TYPE of animal: 

     Select Case SelectedAnimal.AnimalType 
      Case AnimalTypes.Human 
       Dim NewHuman As Human = CType(SelectedAnimal, Human) 
       MsgBox(NewHuman.Shotgun) 

      Case AnimalTypes.Pig 
       Dim Piggy As Pig = CType(SelectedAnimal, Pig) 
       MsgBox(Piggy.PigOnEquality) 
      Case Else 
       MsgBox("This Animal has nothing to say . . .") 

     End Select 
    End Sub 

    Private Sub OnMoveAnimal(ByVal X As Integer, ByVal Y As Integer) 
     SelectedAnimal.Move(X, Y) 
    End Sub 

End Class 
+0

すばらしいポストをありがとう!まさに私がやろうとしていたものではありませんでしたが、かなり近いです。 – Jordan

関連する問題