2

私はポリモーフィズムが初めてで、少し苦労しています。

私は3つのクラスを持っています。基本クラスである Visit クラス。次に、配送と集荷です。

配達も集荷も訪問です。

訪問クラスを参照して、配達と集荷の両方に対応できるようにしたいです。

    public virtual class Visit
    {
    private string customerName;
    private string customerAddress;
    private DateTime arrivalTime;

    public string customername
    {
        //name properties
        set { customerName = value; }
        get { return customerName; }
    }

    public string customeraddress
    {
        //address properties
        set { customerAddress = value; }
        get { return customerAddress; }
    }

    public DateTime arrivaltime
    {
        //time proerties
        set { arrivalTime = value; }
        get { return arrivalTime; }
    }
}

public class Delivery : Visit
/*
 * Polymorphism, Delivery is also a visit.
 */
{
    private string deliveryAddress;
    private string deliveryName;

    public string deliveryaddress
    {
        set { deliveryAddress = value; }
        get { return deliveryAddress; }
    }

    public string deliveryname
    {
        set { deliveryName = value; }
        get { return deliveryName; }
    }

    public string ToString()
    { //return Delivery details
        return deliveryname + " " + deliveryaddress + " " + customername + " " + customeraddress + " " + arrivaltime;
    }

}

public class Pickup : Visit
/*
 * Polymorphism, pickup is also a visit.
 */
{
    public string ToString()
    { //return Pickup details
        return customername + " " + customeraddress + " " + arrivaltime.ToString();
    }
}
}
4

4 に答える 4

0

ポリモーフィズムとは、基本クラスの実装が派生クラスで上書きされる可能性があることを意味します。

ToString()あなたの場合、オーバーライドを除いて、すべてが継承に関するものです。

コード内でメソッドを隠していることに注意してくださいToString()。C# では、親クラスの正確な識別子を使用して、継承されたクラスにメンバーを追加できますが、これはポリモーフィズムではありません。

全体がキーワードでマークされている場合、派生クラスはポリモーフィズムを行います。ToString()overrides

public override string ToString()
{
    return base.ToString(); // Change this line with any custom action
}

その他の詳細は、クラスは仮想化できませんが、メンバーは仮想化できるということです。クラスはregular(ポリモーフィズムを許可する) またはsealed(継承できない) にすることができます。

うーん...アップキャストダウンキャストって何か知ってる?

ダウンキャスティング

より具体的な型への参照のキャスト。例えば:

Visit visit = new Delivery();
Delivery delivery = (Delivery)visit; // This is a downcast!

アップキャスティング

具体性の低い型への参照のキャスト。例えば:

Visit deliveryTypedAsBaseClass = new Delivery() // This is an upcast!

Ok

次に、C# は静的に型付けされた言語であるため、型付けとは、as 型の変数Visitが独自のメンバーにアクセスできることを意味します。Deliveryメンバーにアクセスする必要がある場合は、ダウンキャストする必要があります!

于 2012-12-20T10:31:07.067 に答える
0

virtualまず、基本クラスから削除する必要があります

Visit v=new Pickup();
v.customeraddress = "some address";
v=new Delivery();
v.customeraddress = "some address";

上記の例でわかるように、vは のタイプですVisitが、 のインスタンスを指すようにするPickupDelivery、割り当てられたインスタンス タイプに対して異なる動作をするようにすることができます。

于 2012-12-20T10:16:30.563 に答える
0

基本クラスをインスタンス化しないようにしたい場合 (つまり、Visitオブジェクトが意味をなさない、Pickupまたは aのいずれかである)、基本クラスを asおよび notDeliveryとして宣言できます。abstractvirtual

その後は、好きなだけポリモーフィック コードを使用できます。例えば:

List<Visit> visits = new List<Visit>();
visits.Add(new Pickup{ ... some properties set here ...});
visits.Add(new Delivery{ ... some properties set here ...});

// writes out a pickup via a polymorphic call
Console.WriteLine(visits[0].ToString()) 
// writes out a delivery via a polymorphic call
Console.WriteLine(visits[1].ToString()) 

ただし、配信固有のプロパティを使用する場合は、参照されるオブジェクトvisits[0]が typeであっても、 eg への参照が type であるため、それを使用することはできません。それらを使用するには、オブジェクトのランタイム タイプを確認し、次の行に沿って特定のサブタイプにキャストする必要があります。VisitDelivery

foreach (Visit visit in visits)
{
   if (visit is Delivery)
   {
       Delivery d = (Delivery)visit;
       //delivery specific code here
   }
   else if (visit is Pickup)
   {
       Pickup p = (Pickup) visit;
       //pickup specific code here
   }
   else
   {
       //unknown descendant, panic
   }
}
于 2012-12-20T10:23:39.233 に答える
0

あなたの質問を正しく理解していれば...

あなたのシナリオは、オブジェクトがあり、それが であるか であるかVisitに応じて詳細を取得したいというものです。実行時にまたはオブジェクトを作成している限り、次の操作を実行できます。PickupDeliveryDeliveryPickup

Visit v = GetVisit() //or whatever your method is
if(v.GetType() == typeof(Delivery))
{
    Delivery d = v as Delivery;
}
else //Must be Pickup
{
    Pickup p = v as Pickup;
}

その後、オブジェクトを使用できます。このオブジェクトは、設計上、Visit 変数とそのクラスの一意の変数を表示します。たとえば、...d.customeraddress

これは、Visit オブジェクトが既存のソース (フラット ファイルやデータベースなど) から取得された場合には機能しません。Visitその場合、さらに分類を増やす予定がある場合は、などのクラスのプロパティbool AmIDeliveryまたは Enumeration クラスが必要になります。その後、この変数を見て、それに応じて動作できますが、使用する前にキャスト オブジェクトを作成する必要があります。これが問題になる場合は、例を示します。

于 2012-12-20T10:22:33.503 に答える