この記事は次から転送されます:https : //www.cnblogs.com/yubinfeng/p/4555948.html
前のセクションでは、3つの主要なオブジェクト指向機能の1つのカプセル化について説明しました。これにより、同じオブジェクトで操作できるすべての情報をまとめ、統一された外部呼び出しを実装し、同じオブジェクトの再利用を実現し、結合を減らすという問題が解決されます。
ただし、実際のアプリケーションでは、多くのオブジェクトが同じまたは類似した属性を持っています。たとえば、オブジェクトフルーツツリー(FruitTree)があります。これは、メンバー属性リーフ(リーフ)を持ち、ブルーム(花)を持ち、茎(ステム)を持ち、ツリールート(ルート)、それは成長します(成長メソッド)。
果物の木でもある別のオブジェクトアップルツリー(AppleTree)があり、果物の木のすべての特性があります。次に、プログラミング時にアップルツリーオブジェクトを定義しました。別のオレンジツリー(OrangeTree)、桃の木(PeachTree)がある場合は、このオブジェクトを常にコピーして名前を変更できないのですか?ここでは、2番目のオブジェクト指向機能である継承を使用します。
1. 継承とは
上記のFruitTreeとOrangeTreeの間には「is-a」の関係があります。つまり、「オレンジツリーはフルーツツリー」と言えます。オブジェクト指向プログラミングでは、この関係を「継承」と呼びます。つまり、オレンジツリーはフルーツツリーから継承します。つまり、オレンジの木はフルーツの木の派生物であり、フルーツの木が親クラスであり、オレンジの木が子クラスであるとも言えます。同じリンゴの木も果樹を継承できるので、リンゴの木は果樹のサブクラスとも言えます。ここでは、クラスが複数の派生クラスを持つことができる、つまり、クラスが複数のクラスによって継承されることがわかります。
上記の例を通じて、継承に関連する概念を要約します。
(1)クラスA が別のクラスB のすべての非プライベートデータと操作の定義を、それ自体のコンポーネントの一部またはすべてとして取得できる場合、2つのクラス間に継承関係があると言われています。
(2)継承したクラスBを親クラスまたは基本クラスと呼び、親クラスを継承したクラスA を子クラスまたは派生クラスと呼びます。
2. 継承された特性
上記の例では、リンゴの木が果実の木から継承した場合、リンゴの木は果実の木のすべての属性(葉、根、花)とメソッド(成長)を持ちます。リンゴの木には、独自の果実など、いくつかの固有の属性もあります。 Apple(Apple);同じ桃の木には独自の果物桃(Peach)があるため、継承されたサブクラスは独自の一意のメンバー(プロパティやメソッドなど)を持つことができます。
機能1:親クラスの特性を継承することに加えて、派生クラスは独自の固有の特性を持つこともできます
葉、根、花などのパブリックメンバーに加えて、上記のFruitTreeは、種(落葉性果樹、常緑果樹)や「種」メンバーなどの独自のプライベートメンバーを持つこともできます。サブクラスAppleTreeおよびOrangeTreeによって所有されていないため、プライベートメンバーです。サブクラスが親クラスを継承した後は、親クラスのプライベートメンバーを持つことはできません。
機能2:サブクラスは親クラスのプライベートメンバーを持つことはできません
上記の例では、ツリーにpublicメソッドのGrowth(Growth)がある場合、2つのサブクラスpeach treeとapple treeがあり、サブクラスにもGrowthメソッドがありますが、peach treeとappleツリーの成長プロセスは異なります。この方法を変更して、さまざまな種類の果樹の成長に適応させることができます。
機能3:サブクラスは親クラスの機能を独自の方法で実装できます(つまり、後で具体的に紹介するメソッドの書き換え)。
3。継承された実装
上記の例では、概念は別として、継承についてはよく知っています。簡単に言えば、継承という言葉は生命に由来し、財産の継承、霊的な継承があります。オブジェクト指向プログラミングは、これらの概念を抽象化したものにすぎません。簡単に言えば、「リンゴの木は果実の木です」
コードは上記の例を実装します
1 /// <summary> 2 /// Fruit tree class 3 /// </ summary> 4 class FruitTree 5 { 6 /// <summary> 7 ///名前 8 ///説明:アクセスを保護するために保護された修飾子。アクセスはこのクラスとサブクラスに制限されており、インスタンスにはアクセスできません。 9 /// </ summary> 10保護された文字列名; 11 /// <summary> 12 ///コンストラクタ 13 /// </ summary> 14 public FruitTree() 15 { 16 this.name = "no name"; 17} 18 /// <summary> 19 ///コンストラクタ2 20 /// </ summary> 21 /// <param name = "name"> < 24 this.name = name; 25} 26 object _leaf; 27 object _root; 28 object _flower; 29 string _type; 30 /// <summary> 31 /// leaf(public property) 32 /// </ summary> 33パブリックオブジェクトリーフ 34 { 35 get {return _leaf;} 36 set {_leaf = value;} 37} 38 /// <summary> 39 /// root(パブリックプロパティ) 40 /// </ summary> 41パブリックオブジェクトルート 42 { 43 get {return _root;} 44 set {_root = value;} 45} 46 /// <summary> 66 /// 47 /// Flower(パブリックプロパティ) 48 /// </ summary> 49 public object flower 50 { 51 get {return _flower;} 52 set {_flower = value;} 53} 54 /// <summary> 55 // /カテゴリー(修飾子が定義されていない、デフォルトはプライベート) 56 /// </サマリー> 57文字列タイプ 58 { 59 get {return _type;} 60セット{_type = value;} 61} 62 63} 64 65 /// <summary> 67 ///継承元:Fruit Tree 68 /// </ summary> 69クラスAppleTree:FruitTree 70 { 71 string _myName; 72 /// <summary> 73 ///コンストラクタ 74 ///説明:サブクラスは親クラスの同じコンストラクタを呼び出します。使用する必要があります:base() 75 /// </ summary> 76 public AppleTree ():base() 77 { 78} 79 /// <summary> 80 ///コンストラクタ2 81 ///説明:サブクラスは親クラスの同じコンストラクタを呼び出します。使用する必要があります:base(name) 82 / // </ summary> 83 /// <param name = "name"> </ param> 84 public AppleTree(string name):base(name) 85 { 86 _myName = name; 87} 90 ///果物の名前を返す 91 /// </ summary> 88 89 /// <summary> 92 /// <returns> </ returns> 93 public string MyFruitName() 94 { 95 return "I am:" + _myName + "; my fruit is called:Apple"; 96} 97} 98 /// <summary> 99 /// Orange tree class 100 ///継承元:Fruit tree class 101 /// </ summary> 102 class OrangeTree:FruitTree 103 { 104 string _myName; 105 /// <summary> 106 ///コンストラクター 107 ///説明:サブクラスは親クラスの同じコンストラクターを呼び出すため、使用する必要があります:base() 108 /// </ summary> 109 public OrangeTree():base() 110 { 111} 112 /// <概要> 113 ///コンストラクタ2 114 ///説明:サブクラスは親クラスの同じコンストラクターを呼び出します。使用する必要があります。base(name) 115 /// </ summary> 116 /// <param name = "name"> </ param> 117 public OrangeTree(string name):base(name) 118 { 119 _myName = name; 120} 121 122 /// <summary> 123 ///戻る果物の名前 124 /// </ summary> 125 /// <returns> </ returns> 126 public string MyFruitName() 127 { 128 return "I am:" + _myName + "; my fruit is called:orange"; 129 } 130}
サブクラスを呼び出します。
//サブクラスを 呼び出すAppleTree appleTree = new AppleTree( "Apple Tree"); string myName = appleTree.MyFruitName(); //返される結果は次のとおりです:私は:リンゴの木です;私の果実は呼び出されます:リンゴ
//サブクラスを
呼び出すOrangeTree orangeTree = new OrangeTree( "橙树");
string myName = orangeTree。MyFruitName();
//返される結果は次のとおりです:私は:オレンジツリーです;私のフルーツは呼び出されます:オレンジ
このコードを通じて、ベースクラスフルーツツリーがあることがわかります。サブツリーAppleTree.MyFruitName()は、このメソッドの名前を異なるサブクラスで返すため、何百ものツリーがあり、継承は1つだけ必要です。一意にすることができます。つまり、継承の特性として、一意のメンバーを追加できます。固有の特性はサブクラスごとに個別に定義する必要がありますが、親クラスのメンバーを共有することで多くの作業を節約でき、最も重要なプログラムの構造がより明確になり、保守が容易になります。
4. 継承の短所
このタイトルを見て、オブジェクト指向の継承には非常に多くの利点があるため、まだ不利な点があるので、友人たちは驚かれるかもしれません。もちろん、世界には完璧なものは何もなく、継承もそうです。
短所:親クラスが変更され、子クラスが変更されます。
欠点2:継承によってパッケージ化が解除され、親クラスの詳細が子クラスに公開されます。
前のセクションでは、カプセル化の独立した機能はカップリングを減らすことであり、再利用を実現するためにそれを継承することでカップリングが増加すると述べました。
友人が絡んでいる場所といえば、継承を使用するかどうかにかかわらず、答えは「はい」です。その利点と光は、欠点、つまりより多くの利点を覆い隠します。ここでは、その欠点を説明するために、使用プロセスにおいてその欠点の影響をできるだけ回避するように注意を喚起します。
では、継承をどのようにうまく利用できるでしょうか。次の点に注意する必要があります。
a。2つのオブジェクト間の関係が「is a」である場合、継承を使用できます(たとえば、リンゴの木はツリーです); b。2つのオブジェクトが「as」関係である場合、継承を使用することは適切ではありません(手が人間の一部であるなど) 、手を相続させることはできません);
継承の長所と短所に関しては、1つのことを覚えておく必要があります。継承を合理的な方法で使用すると、盲目的にではなく、最良の結果を得ることができます。
オブジェクト指向の3つの主要な機能の1つである継承は、オブジェクト指向プログラミングを学ぶ上での最優先事項であると言え、このセクションはこのシリーズの焦点と言えるので、誰もいません。
友達、また早朝なので明日も書き続けます。最後に、規約に従って、継承を使用するときに注意する必要があるいくつかのポイントを記述します。
重要なポイント:
1:親クラスのプライベートメンバー。派生クラスにはアクセスできません。
2:C#は、クラスが直接の基本クラスを1つだけ持つことができることを要求します。
3: "sealed"キーワードで変更されたクラスは継承できません。
4:「protected」によって変更されたメンバーまたはデータは、派生クラスから直接アクセスでき、「ファミリーで共有できるシークレット」に属します。
5:「base」キーワードを活用して、デフォルトのコンストラクターを使用する代わりに、適切なカスタム基本クラスコンストラクターが呼び出されることを示します。
6:継承は、最良の結果を達成するために合理的な使用を必要とします。一般に、継承は「ある」関係ではなく「ある」関係に適用されます。