2017-12-25 10 views
0

免責事項:私はこのコーディングの世界にはまったく初心者です! 私のコースではC#を学ぶ上で、私はこの記事を読んでいます。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywordsc#:継承した基本メソッドを呼び出すときの制御の流れ。派生クラスでnewとして設定された基本仮想メソッドが呼び出されます

コード:

public class Car 
{ 
    public void DescribeCar() 
    { 
     Console.WriteLine("Car: Four wheels and an engine."); 
     ShowDetails(); 
    } 

    public virtual void ShowDetails() 
    { 
     Console.WriteLine("Car: Standard transportation."); 
    } 
} 

public class ConvertibleCar : Car 
{ 
    public new void ShowDetails() 
    { 
     Console.WriteLine("ConvertibleCar: A roof that opens up."); 
    } 
} 

ConvertibleCar myCC = new ConvertibleCar(); 
myCC.DescribeCar(); 
myCC.ShowDetails(); 

//Output 
Car: Four wheels and an engine. 
Car: Standard transportation. 
ConvertibleCar: A roof that opens 

が質問:出力の私の第二と第三行に:私は私の理解と期待し、私は「屋根開くよりもConvertibleCar」を取得する必要があります。 派生クラスで直接、および基本クラスのメソッド内からShowDetailsを直接呼び出す場合はどうなりますか? PS:showdetialsは、派生クラスでnewに設定されています。

+0

私はちょうど、今、同様の問題を発見したと思い、私は今、それを通過しています。 https://stackoverflow.com/questions/17717570/why-does-calling-a-method-in-my-derived-class-call-the-base-class-method – TechieSahal

+0

それは私を助けませんでした。 – TechieSahal

+0

@Sweeper Rainman皆さんからのご意見が私には分かりました。 – TechieSahal

答えて

0

newの代わりにoverrideを使用し、あなたの期待される出力を得るために:

public override void ShowDetails() 
{ 
    Console.WriteLine("ConvertibleCar: A roof that opens up."); 
} 

あなたがnewを使用する場合、は、基本クラスでShowDetails方法を陰には。つまり、派生クラスの実装は、派生クラスの変数からメソッドを呼び出すときにのみ使用されます。

overrideは何か異なります。 ShowDetailsがオーバーライドされている場合、変数の型に関係なく、オブジェクトの基底型が派生クラスである限り、派生クラスの実装が常に使用されます。

これは、出力の2番目の行が異なる理由を説明しています。 2行目は、この行から製造される:

public void DescribeCar() 
{ 
    Console.WriteLine("Car: Four wheels and an engine."); 
    ShowDetails(); <-------- 
} 

ShowDetailsthis.ShowDetailsを意味します。 thisCarのタイプですが、実際にはConvertibleCarのオブジェクトを指します。 ShowDetailsが隠されているので(thisがタイプCarであるため!)、それはCarの実装を呼び出し

+0

"ShowDetailsはこれを意味します.Show詳細。これはCar型ですが、実際にはConvertibleCarのオブジェクトを参照します.ShowDetailsはシャドーされているため、Carの実装を呼び出します(Car型です)。 もう少し明快です、ありがとうございます。 しかし、私がConvertibleCarオブジェクトをインスタンス化するとき、継承によって受け取ったShowDetails()メソッドは派生クラスの実装を指していませんか? 継承シナリオでオブジェクトが実際にインスタンス化/使用される方法について、いくつかの基本を明確にしていない可能性があります。 – TechieSahal

+0

@TechieSahalはい、派生クラスの実装を指します。そのため、第3行目の出力に対して 'ConvertibleCar'の実装を取得するのです。新しいConvertibleCarを作成すると、そのオブジェクトは2つの 'ShowDetails'メソッドを持っています。一つは 'Car'の実装であり、もう一つは' ConvertibleCar'の実装です。型が 'ConvertibleCar'である場合、' Car'実装は隠されています。型が 'Car'の場合、' ConvertibleCar'実装は隠されています。 – Sweeper

0

newを使用すると、実際にはShowDetailsがシャドーされます(実際には、VB.NETにはShadowsというキーワードがあります)。また、newShadowDetailsをプロパティにすることができます!

の2つのクラスを作成してみましょう:ベースをして派生:

class Base 
{ 
    public virtual int GetInt() 
    { 
     return 10; 
    } 
} 

class Derived : Base 
{ 
    public new int GetInt() 
    { 
     return 11; 
    } 
} 

、のは、それらをテストしてみましょう:

Base b; 
Derived d; 
int x; 

b = new Derived(); 
d = new Derived(); 

x = b.GetInt(); // x = 10 [Base.GetInt()] 
x = d.GetInt(); // x = 11 [Derived.GetInt()] 

ご覧のとおり、bが派生割り当てられているが、それはまだBaseを指します。

しかし、まったく違うことをやろう - メソッドをプロパティに変えよう!我々はDerivedクラスのGetInt()メソッドを持っていない

x = d.GetInt(); // x = 10 

しかし、待って、:私たちは、以前のテストコードを実行すると

class Derived : Base 
{ 
    public new int GetInt 
    { 
     get { return 11; } 
    } 
} 

は、今、私たちはx = 10ていることがわかります!なぜコードがコンパイルされるのですか?これは簡単です。GetIntプロパティを持つGetInt()メソッドをシャドウしたので、今度はGetInt()Baseから呼び出されます!もっと混乱させるために、IntelliSenseはd変数にGetInt()メソッドを表示しませんが、コンパイラは満足しています。 11を取得するには、プロパティを呼び出す必要があります:

x = d.GetInt; 

ます。また、デリゲートにGetInt()方法回すことができます。

class Derived : Base 
{ 
    public new delegate int GetInt(); 
} 

をし、それを使用します。

Derived.GetInt getIntDelegate =() => 12; 
Console.WriteLine(getIntDelegate()); // Prints 12 
0

に使用newキーワード隠蔽ベース部材/方法。そう

public new void ShowDetails() 
{ 
    Console.WriteLine("ConvertibleCar: A roof that opens up."); 
} 

ShowDetails方法はConvertibleCarクラスのnew方法であり、基本クラスShowDetails方法は全く異なっており、それはinheretance鎖ではありません。たとえば、ConvertibleCarクラスにShowDetails2のようなメソッド名を定義できるとします。それは同じ場合です。

また、newの代わりにkeywordを使用すると、ConvertibleCarクラスはShowDetailsメソッドをオーバーライドします。

public class ConvertibleCar : Car 
{ 
    public override void ShowDetails() 
    { 
     Console.WriteLine("ConvertibleCar: A roof that opens up."); 
    } 
} 

出力は次のようになります。

Car: Four wheels and an engine. 
ConvertibleCar: A roof that opens. 
ConvertibleCar: A roof that opens. 
+0

うわー!このプラットフォームは素晴らしいです。 15分後に返事が届きました! クイックフィードバックに感謝します。しかし、私はまだそれを得ることができませんでした。 私が理解したもの: 派生クラスのメソッドにnewキーワードを使用すると、そのメソッドはその派生クラスのインスタンスを使用するときに優先順位を取得します。 ここでは、私はConvertibleCarのインスタンスを使用しており、変数型もConvertibleCarです。 そして、ShowDetails()が継承された基本クラスメソッドDescribecar()内で呼び出されたときにのみ、私は適切な振る舞いを持っています。 – TechieSahal

+0

はい、あなたは正しいです。ご覧のとおり、 "new"キーワードは基本クラスメソッドを隠します。 – lucky