web-dev-qa-db-ja.com

C#の純粋仮想メソッド?

クラスを抽象化するように言われました:

public abstract class Airplane_Abstract

そして、move virtualというメソッドを作成します

 public virtual void Move()
        {
            //use the property to ensure that there is a valid position object
            double radians = PlanePosition.Direction * (Math.PI / 180.0);

            // change the x location by the x vector of the speed
            PlanePosition.X_Coordinate += (int)(PlanePosition.Speed * Math.Cos(radians));

            // change the y location by the y vector of the speed
            PlanePosition.Y_Coordinate += (int)(PlanePosition.Speed * Math.Sin(radians));
        }

そして、他の4つのメソッドは「純粋な仮想メソッド」でなければなりません。それは何ですか?

それらはすべて今すぐこのように見えます:

public virtual void TurnRight()
{
    // turn right relative to the airplane
    if (PlanePosition.Direction >= 0 && PlanePosition.Direction < Position.MAX_COMPASS_DIRECTION)
        PlanePosition.Direction += 1;
    else
        PlanePosition.Direction = Position.MIN_COMPASS_DIRECTION;  //due north
}
38
David Brewer

私の推測では、「純粋な仮想」メソッドを作成するように言った人は、C#プログラマーではなくC++プログラマーでしたが...同等のメソッドは抽象メソッドです。

public abstract void TurnRight();

これにより、具体的なサブクラスがTurnRightを実際の実装で強制的にオーバーライドします。

74
Jon Skeet

「純粋な仮想」はC++の用語です。 C#に相当するものは抽象メソッドです。

11
David Yaw

それらはおそらく、メソッドがabstractとマークされるべきであることを意味します。

 public abstract void TurnRight();

次に、サブクラスでオーバーライドする必要がない空の仮想メソッドとは対照的に、サブクラスでそれらを実装する必要があります。

8
Justin

または、インターフェースを使用することもできますが、いくつかの小さな制限が必要だと考えました。

public interface IControllable
{
    void Move(int step);
    void Backward(int step);
}

public interface ITurnable
{
   void TurnLeft(float angle);
   void TurnRight(float angle);
}

public class Airplane : IControllable, ITurnable
{
   void Move(int step)
   {
       // TODO: Implement code here...
   }
   void Backward(int step)
   {
       // TODO: Implement code here...
   }
   void TurnLeft(float angle)
   {
       // TODO: Implement code here...
   }
   void TurnRight(float angle)
   {
       // TODO: Implement code here...
   }
}

ただし、すべて実装IControllableITurnableの両方の関数宣言が割り当てられている必要があります。そうでない場合、コンパイラエラーが発生します。オプションの仮想実装が必要な場合は、abstract classは、仮想メソッドの場合はinterfaceを使用した仮想メソッドです。

実際、interface関数とabstract関数には違いがあり、interfaceは関数のみを宣言します、すべてinterface関数privateprotectedなどの派手なクラスプロパティがないため、すべて公開する必要があるため、abstract関数は実装なしの実際のクラスメソッドおよび派生クラスでの実装を強制。したがって、privateprotectedを配置し、abstract関数を使用してメンバー変数にアクセスできます。の時間クラスの継承関係は実行時に分析されるため、遅い。 (別名vtable)

4
Steve Fan

純粋な仮想関数はC++の用語ですが、派生クラスとその派生クラスで実装される関数が抽象クラスではない場合、C#で使用されます。

abstract class PureVirtual
{
    public abstract void PureVirtualMethod();
}

class Derivered : PureVirtual
{
    public override void PureVirtualMethod()
    {
        Console.WriteLine("I'm pure virtual function");
    }
}
4
AuserP

その場合、Airplane_Abstractクラスに実装はありませんが、クラスのコンシューマーの「継承者」に実装を強制します。

Airplane_Abstractクラスは、抽象関数を継承して実装するまで使用できません。

2
AnthonyLambert

http://en.wikipedia.org/wiki/Virtual_function

「オブジェクト指向プログラミングでは、仮想関数または仮想メソッドは、同じシグネチャを持つ関数によって継承クラス内で動作をオーバーライドできる関数またはメソッドです。」

Googleは常にあなたの友達です。

1
dotalchemy