2016-05-31 2 views
0
public class BaseClass 
    { 
     public virtual void Display() 
     { 
      Console.WriteLine("I am Base Class"); 
     } 

     public void BaseClassMethod() 
     { 
      Console.WriteLine("I am Base Class Method"); 
     } 
    } 

    public class DerivedClass : BaseClass 
    { 
     public override void Display() 
     { 
      Console.WriteLine("I am Derived Class"); 
     } 

     public void DerivedClassMethod() 
     { 
      Console.WriteLine("I am Derived Class Method"); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      BaseClass bc = new BaseClass(); 
      bc.Display(); 
      bc.BaseClassMethod(); 

      Console.WriteLine("--------------"); 

      DerivedClass dc = new DerivedClass(); 
      dc.Display(); 
      dc.BaseClassMethod(); 
      dc.DerivedClassMethod(); 

      Console.WriteLine("--------------"); 

      BaseClass bc2 = new DerivedClass(); 
      bc2.Display(); 
      bc2.BaseClassMethod(); 
      //bc2.DerivedClass(); --> I can't reach b2.DerivedClass() method 

      Console.ReadLine(); 
     } 
    } 

皆さん。なぜ、どこで、ベースクラス参照から派生したクラスオブジェクトを作成して使用したいのかについて、私は心を澄まそうとしています。私は仮想がどのように動作するか知っている私は派生クラスが基本クラスであり、私は仮想メソッドをオーバーライドすることができます知っている。私は基本クラスの非仮想メソッドに到達することができます。しかし、私はどこで、なぜこのスタイルのオブジェクト作成を使いたいのかを知りたい。サンプルコードの最後の部分のように。ベースクラス参照でオブジェクトを作成する必要があるのはなぜですか?

BaseClass bc2 = new DerivedClass(); 

派生クラスのメソッドに到達できないため、派生クラスのメソッドを使用できません。しかし、それは新しいDerivedClassのためにまだクラスに派生しています。私が通常のDerivedClassを使用する場合、d = new DerivedClass();スタイル、私は両方のクラスのメソッドを使用することができます。私はちょうど私がこのスタイルを使いたい理由と状況を見つけることができません。誰かが私にどのような状況で私を見せてくれるのがうれしいです。基本クラス参照から派生クラスオブジェクトを使用しなければならないので、このスタイルが言語に存在することを理解できます。私はなぜそれがうまくいかないのか、それともどういうことを求めているのか分かりません。状況を知りたいありがとうございました。

+0

あなたは 'クラス継承 'の読書/研究を行っていますか?おそらく、あなたは 'OOP'で' C#MSDN Google Search'を見て、どこでどのように、なぜ、どのように、そしてなぜそれが良いのかを理解することができます。 – MethodMan

+0

あなたは1つの基本クラスと1つの派生クラスしか持っていないとき、多くの価値を見つける。共通の機能を持つ複数のクラスがありますが、継承の恩恵を受ける展開のパスも異なります。 – Jonesopolis

+0

概要:基本クラスのフィーチャセットが提供するものよりも魅力的なものは、オブジェクトが使用されないことを、読者に伝えます。派生型の宣言は「論理的なノイズ」になります。必要以上に複雑にならないようにすることです。ジョブに合ったツールを使用してください。 –

答えて

2

二つの主な用途があります。

1)は、複数の種類のコレクション

私が円を保持することができますリストを持っているあなたの例を少し

public class Shape 
{ 
    public virtual void Display() 
    { 
     Console.WriteLine("I am a Shape"); 
    } 

    public void BaseClassMethod() 
    { 
     Console.WriteLine("I am Base Class Method"); 
    } 
} 

public class Square : Shape 
{ 
    public override void Display() 
    { 
     Console.WriteLine("I am Square"); 
    } 

    public void DerivedClassMethod() 
    { 
     Console.WriteLine("I am Derived Class Method"); 
    } 
} 



public class Circle : Shape 
{ 
    public override void Display() 
    { 
     Console.WriteLine("I am Circle"); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Shape> shapes = new List<Shape(); 
     shapes.Add(new Square()); 
     shapes.Add(new Circle()); 

を変更でき、正方形、および一般的な図形はすべて1つのコレクションに含まれます。

2)多型

我々は、しかし、我々はそれが何であれ親切、それは持っていることを知っていますされShape変数shapeの種類がわからない前のコード

  foreach(Shape shape in shapes) 
     { 
      shape.Display(); 
     } 

に引き続きDisplay()メソッドを呼び出すと、正しい情報が表示されます。

多型は、何かの関数を呼び出す必要があるが、上のような基本型のコレクションを引っ張っているために何かがある特定の型を知らない場合や、どのような種類のShapeでも構いません。なぜなら、その機能を実行するために特定の種類を知る必要がないからです。

public static void LogDisplay(Shape shape) 
    { 
     Console.WriteLine("I am about to call shape.Display()"); 
     shape.Display(); 
     Console.WriteLine("I am just called shape.Display()"); 
    } 
+0

あなたの答えをありがとう。他にも有益な答えがありますが、それは最初のものだったので私はあなたを受け入れます。これは、私が四角形や円をshape.Add(新しいSquare())のように作成するときに意味します。このオブジェクトは、List内のベースクラス参照で作成されます。 – alpersilistre

+1

私はあなたの質問を理解することは完全にはわかりませんが、答えは「はい」だと思います。 –

2

私のお気に入りの例は、人々が使用を理解することができるため、ロギングです。私はウェブサイトを作成すると想像してください。私がサイトを開発しているときは、簡単にアクセスできるので、私は自分のファイルシステムにログインしたいと思っています。 Webサイトを展開するときに、そのマシンのファイルシステムに直接アクセスできない可能性があるため、イベントログにログを記録します。

しかし、私は物事が記録されている場所を変更したいだけです。実際のテキストがどのように見えるかを基底クラスで構造化します。だから私は、テキストをフォーマットし、私の基本クラスを持っている:

public class FileLogger : BaseLogger 
{ 
    public FileLogger(string filename) 
    { 
     //initialize the file, etc 
    } 

    public override void LogException(Exception ex) 
    { 
     var string = GetStringFromException(ex); 
     File.WriteAllLines(...); 
    } 

    public override void LogException(Exception ex) 
    { 
     var string = GetStringFromUserMessage(ex); 
     File.WriteAllLines(...); 
    } 
} 

とイベントログに記録します私のクラス:

public abstract class BaseLogger 
{ 
    public abstract void LogException(Exception ex); 
    public abstract void LogUserMessage(string userMessage); 

    protected string GetStringFromException(Exception ex) 
    { 
     //.... 
    } 

    protected string GetStringFromUserMessage(string userMessage) 
    { 
     //.... 
    } 
} 

今私は、ファイル・システムにログインするクラスを持つことができます

public class EventLogger : BaseLogger 
{ 
    public EventLogger() 
    { 
     //initialize the eventlog, etc 
    } 

    public override void LogException(Exception ex) 
    { 
     var string = GetStringFromException(ex); 
     EventLog.WriteEntry(...); 
    } 

    public override void LogException(Exception ex) 
    { 
     var string = GetStringFromUserMessage(ex); 
     EventLog.WriteEntry(...); 
    } 
} 

今私のプログラムでは、私は自分のクラスに1つを注入するとき私はBaseLoggerがあることを気にします。実装の詳細は無関係ですが、私が使用しているものであればLogExceptionLogUserMessageができることを知っています。

私は私ではない思いやり、私はを使用するクラスを派生し、そこから利益を得ロガーを使用してです。これは、それぞれの派生クラスを基本クラスのように扱う利点です。私はプログラムを気にせずにそれらを交換することができます。

0

派生クラスの使用可能性の背後にある多くの理由は、繰り返しコードの最小化に関係していると思います。私は車の属性や能力を記述するためにお聞きしました、その後、電気自動車のために同じことを行うためにお聞きした場合、あなたはそれだけ見つけるだろう実際の生活の例... を参照するために

の属性と能力の両方が共有されます。したがって、2つのクラスを別々にするのではなく、基本クラスのCarを作成し、そのクラスからelectricCarを派生させる方が効率的です。その後、派生クラス内の電気自動車の具体的な相違点のみを考慮する必要があり、共有されているすべての属性と能力が引き継がれます。

これは、基本クラスと派生クラスの有用性を理解するのに役立ちます。非常に単純化されていますが、あなたがそのコンセプトを理解するのに役立つかもしれないと感じています!

1

これは主にコードの再利用性と拡張性に関連する多くの理由があります。言い換えれば、全体をたくさん書き換える必要なく簡単に小さな変更や拡張を行うことができます。

異なるデータベース(または異なるテーブル構造)をサポートする必要があるソフトウェアを異なる顧客に使用している実際の例です。そのためには、共通の基本クラスから実装を派生させ、実装の詳細をプログラムの残りの部分に影響を与えずに変更することができます。

また、これは次に、メインプログラムにあなたがかもしれ

public abstract class ProviderBase 
{ 
    public abstract Employee[] GetAllEmployees(); 
} 

public class MySqlProvider:ProviderBase 
{ 
    public override Employee[] GetAllEmployees() 
    { 
     string select = "select * from employees"; 

     //query from mysql ... 
    } 

} 

public class MsSqlProvider : ProviderBase 
{ 
    public override Employee[] GetAllEmployees() 
    { 
     string select = "select * from user u left join employee_record e on u.id=e.id"; 

     //query from mysql ... 
    } 
} 

に説明されている「『インターフェース』ではなく、 『実装』にプログラム 」設計原理を以下の使用する主な理由を構成して、データベースの実装の種類を変更したりDependency Injection

ProviderBase provider = null; 
if(databaseType == "MySql") 
{ 
    provider = new MySqlProvider(); 
} 
else if (databaseType == "MsSql") 
{ 
    provider = new MsSqlProvider(); 
} 

var employees = provider.GetAllEmployees(); 
//do something 
0

することができ基底クラスは再利用多型である

だから、状況に応じてクラス作成することができます:あなたはどのような種類を知っていない場合でも、あなたはbcを使用することができ、次のアプリケーションで

BaseClass bc 
if(case1) 
    bc = new DerivedClass1(); 
else 
    bc = new DerivedClass2(); 

をそれはコンパイル時です。あなたはそれを渡すことができます。派生クラスのメソッドは、あなたが実際に持っている派生クラスの種類を知っている場合にのみ使用できます。その後、変換を行うことができます。

DerivedClass1 dc = bc as DerivedClass1; 
dc.DerivedClassMethod() 
関連する問題