[.netオブジェクト向けプログラミング基礎](13)オブジェクト向け三大特性——マルチステート
43462 ワード
[.netオブジェクト向けプログラミング基礎](13)オブジェクト向け三大特性——マルチステート
前の2節では,オブジェクト向けのカプセル化と継承特性を理解し,オブジェクト向けのもう1つの大きな特性がマルチステートである.前のパッケージや継承よりも,多態という概念はそれほど理解できない.私たちはやはり一つの事例から始めます.
会社は最近、情操を陶冶するために、いくつかの動物(Animal)を飼っています.猫(Cat)、犬(Dog)、羊(Sheep)があります.これらの動物は共通の特性を持っていて、食べることができます.以上、動物類(Animal)とそのメンバー(Eat方法、Shout方法)を設計して、これらの動物の共通の特徴を表すことができますが、猫に注目すると、猫はこの2つのメンバー(魚を食べ、ニャーニャーニャー鳴く)を実現します.犬に注目すると、犬はこの2つのメンバー(肉とワンワン鳴く)を実現します.
1.マルチステートとは?
上記の例は典型的なマルチステートであり、親クラスの一部のメンバーであり、子クラスが継承された後に書き換えて異なる機能を実現する.
マルチステート:同じ操作が異なるオブジェクトに作用し、異なる解釈があり、異なる実行結果を生成することができます.これが多態であり,この特性を多態性と呼ぶ.
2.多態の分類
マルチステート性は2つに分けられ,1つはコンパイル時のマルチステート性,1つは実行時のマルチステート性である.
コンパイル時のマルチステート:コンパイル時のマルチステートは、リロードによって実現されます.非虚のメンバーにとって、システムはコンパイル時に、伝達されたパラメータ、返されたタイプなどの情報に基づいて、どのような操作を実現するかを決定する.
実行時のマルチステート:実行時のマルチステートとは、システムが実行されるまで、実際の状況に応じてどのような操作を実現するかを決定することです.C#での実行時のマルチステートは、ダミーメンバーを上書きすることによって実現されます.
3.マルチステートの実現
マルチステートには2つあることを知っています.1つはコンパイル時にリロードで実現し、もう1つは実行時に書き換えたり上書きしたりすることで実現します.では、どのように実現しますか.
3.1コンパイル時マルチステート:リロード(overload)
≪リロード|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload
注意:
A.リロードの定義から見ると、リロードはコンパイル時のマルチステートである
B.リロードは事前にリロード可能な方法を定義する必要はなく、キーワードがない
C.リロードは、1つのクラス内のいくつかのパラメータが異なり、名前が同じ方法にすぎない.
また、本節では、情操を陶冶する動物の例を説明します.コードは以下の通りです.
3.2運転時マルチステート:書き換え
書き換えには、override修飾子とnew修飾子の2種類があります.次に、2つの書き換えの使用方法と異同を例に挙げます.
オーバーライド(override):オーバーロードとも呼ばれ、オーバーライドとは親クラスの虚関数または抽象関数に対するサブクラスの「オーバーライド」(これは、オーバーロードをオーバーライドと翻訳する本がある理由)を指すが、この「オーバーライド」とnewキーワードでオーバーライドするのは異なる.
以下、本節の開題前の例で、書き換えを実現します.コードは以下の通りです.
書き換え(new)
new:オーバーライドとは、異なるクラス(ベースクラスまたは派生クラス)に2つ以上の戻りタイプ、メソッド名、パラメータが同じであるが、メソッド体が異なるメソッドを指す.ただし、このオーバーライドは表面上のオーバーライドであるため、非表示とも呼ばれ、オーバーライドされた親メソッドは呼び出すことができる.
次の例で説明します.コードは次のとおりです.
次のように呼び出し方法を変更します.
派生クラスDogのEat()メソッドがnew修飾を使用する場合,DogのオブジェクトがAnimalオブジェクトに変換された後,AnimalクラスのEat()メソッドが呼び出されることが分かる.実際には,newキーワードを用いた場合,DogにおけるEat()メソッドとAnimalにおけるEat()メソッドとは無関係の2つのメソッドとなるが,それらの名前はたまたま同じであると理解できる.したがって、AnimalクラスのEat()メソッドは、使用されていないかvirtual修飾されていないか、アクセス権がどうであれ、ないかにかかわらず、DogのEat()メソッドには影響しません(newキーワードが使用されているため、DogクラスがAnimalクラスからEat()メソッドを継承していない場合、コンパイラは警告を出力します).
これは設計者が意図的に設計したものだと思います.私たちは時々このような効果を達成しなければならないからです.厳密にはnewを用いて多態を実現するとは言えず,特定の場合にたまたま多態の効果を実現したとしか言いようがない.
3.3要点:
a.マルチステートはオブジェクト向けの重要な特性の一つであり、同じ操作が異なるオブジェクトに作用し、異なる解釈があり、異なる実行結果を生成することができることを指す.
b.マルチステートは2種類に分けられる:1つはコンパイル時のマルチステートであり、リロードを用いて実現する.もう1つは、実行時のマルチステートであり、書き換えを使用して実現される.
c.書き換えにはoverrideキーワードとnewキーワードの2種類がある
d.new書き換えは実際には親メソッドの非表示であり,上書きされた親メソッドを呼び出すことができる.したがってnewは、書き換える(または非表示)親メソッドを虚メソッドまたは抽象メソッドとして定義する必要はありません.ただし、親メソッドが虚メソッドまたは抽象メソッドの場合、親メソッドが上書きされ、そうでない場合は非表示になります.
e.リロードとオーバーライドの発生条件:リロードは、必然的に1つのクラスで発生し、関数名が同じで、パラメータタイプまたは順序が異なることでリロードを構成し、戻りタイプとは関係なく書き換えが発生し、必然的にベースクラスと派生クラスで発生し、そのクラス関数はvirtualで修飾され、派生クラスはoverrideで修飾され、サブクラスにベースクラスと同じ名前(パラメータが異なる)の非虚関数を書く.ベースクラスの関数が非表示になり、コンパイル後にNewキーワードnew修飾の使用を求めるメッセージが表示されます.
非表示、子クラスでnewで親を非表示にする方法
f.new上書きと書き換え、リロードの違い:
子と親のパラメータが異なる場合
ベースクラス関数が虚関数でない場合、ベースクラス関数は非表示になります.(サブクラスとベースクラスは同じ範囲ではないので、リロードではありません)
ベースクラス関数が虚関数である場合、ベースクラス関数は非表示になります.(サブクラスとベースクラスが同じ範囲にないため、リロードではありません;パラメータが異なるため書き換えではありません)
子と親のパラメータが同じ場合
ベースクラス関数が虚関数でない場合、ベースクラス関数は非表示になります.(サブクラスとベースクラスは同じ範囲ではないので、リロードではありません.ベースクラスは虚関数ではないので、非表示で書き換えではありません)
ベースクラス関数が虚関数である場合、ベースクラス関数は上書きされます.(サブクラスとベースクラスは同じ範囲ではないので、リロードではありません)
==============================================================================================
ディレクトリに戻る<もしあなたに役に立つならば、覚えていて推薦して、分からない地方あるいは書くのが間違っている地方があって、多く交流してください>
==============================================================================================
前の2節では,オブジェクト向けのカプセル化と継承特性を理解し,オブジェクト向けのもう1つの大きな特性がマルチステートである.前のパッケージや継承よりも,多態という概念はそれほど理解できない.私たちはやはり一つの事例から始めます.
会社は最近、情操を陶冶するために、いくつかの動物(Animal)を飼っています.猫(Cat)、犬(Dog)、羊(Sheep)があります.これらの動物は共通の特性を持っていて、食べることができます.以上、動物類(Animal)とそのメンバー(Eat方法、Shout方法)を設計して、これらの動物の共通の特徴を表すことができますが、猫に注目すると、猫はこの2つのメンバー(魚を食べ、ニャーニャーニャー鳴く)を実現します.犬に注目すると、犬はこの2つのメンバー(肉とワンワン鳴く)を実現します.
1.マルチステートとは?
上記の例は典型的なマルチステートであり、親クラスの一部のメンバーであり、子クラスが継承された後に書き換えて異なる機能を実現する.
マルチステート:同じ操作が異なるオブジェクトに作用し、異なる解釈があり、異なる実行結果を生成することができます.これが多態であり,この特性を多態性と呼ぶ.
2.多態の分類
マルチステート性は2つに分けられ,1つはコンパイル時のマルチステート性,1つは実行時のマルチステート性である.
コンパイル時のマルチステート:コンパイル時のマルチステートは、リロードによって実現されます.非虚のメンバーにとって、システムはコンパイル時に、伝達されたパラメータ、返されたタイプなどの情報に基づいて、どのような操作を実現するかを決定する.
実行時のマルチステート:実行時のマルチステートとは、システムが実行されるまで、実際の状況に応じてどのような操作を実現するかを決定することです.C#での実行時のマルチステートは、ダミーメンバーを上書きすることによって実現されます.
3.マルチステートの実現
マルチステートには2つあることを知っています.1つはコンパイル時にリロードで実現し、もう1つは実行時に書き換えたり上書きしたりすることで実現します.では、どのように実現しますか.
3.1コンパイル時マルチステート:リロード(overload)
≪リロード|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload|overload
注意:
A.リロードの定義から見ると、リロードはコンパイル時のマルチステートである
B.リロードは事前にリロード可能な方法を定義する必要はなく、キーワードがない
C.リロードは、1つのクラス内のいくつかのパラメータが異なり、名前が同じ方法にすぎない.
また、本節では、情操を陶冶する動物の例を説明します.コードは以下の通りです.
1 /// <summary>
2 /// ( : )
3 /// </summary>
4 class Dog
5 {
6 /// <summary>
7 ///
8 /// </summary>
9 public void Shout()
10 {
11 Console.WriteLine(" !");
12 }
13
14 /// <summary>
15 /// ( )
16 /// </summary>
17 public void ShoutCount(int count)
18 {
19 int i = 0;
20 string shout = "";
21 do
22 {
23 shout += " !";
24 i++;
25 } while (i <= count);
26 Console.WriteLine(shout);
27 }
28 }
//
Dog dog = new Dog();
dog.Shout();
dog.ShoutCount(5);
3.2運転時マルチステート:書き換え
書き換えには、override修飾子とnew修飾子の2種類があります.次に、2つの書き換えの使用方法と異同を例に挙げます.
オーバーライド(override):オーバーロードとも呼ばれ、オーバーライドとは親クラスの虚関数または抽象関数に対するサブクラスの「オーバーライド」(これは、オーバーロードをオーバーライドと翻訳する本がある理由)を指すが、この「オーバーライド」とnewキーワードでオーバーライドするのは異なる.
以下、本節の開題前の例で、書き換えを実現します.コードは以下の通りです.
1 /// <summary>
2 /// ( )
3 /// </summary>
4 class Animal
5 {
6 /// <summary>
7 ///
8 /// :
9 /// </summary>
10 protected string name;
11
12
13 /// <summary>
14 ///
15 /// </summary>
16 /// <param name="name"></param>
17 public Animal(string name)
18 {
19 this.name=name;
20 }
21
22 /// <summary>
23 /// ( )
24 /// </summary>
25 public virtual string MyName
26 {
27 get { return this.name; }
28
29 }
30
31 /// <summary>
32 /// ( )
33 /// </summary>
34 public virtual void Eat()
35 {
36 Console.WriteLine(" !");
37 }
38
39 /// <summary>
40 /// ( )
41 /// </summary>
42 public virtual void Shout()
43 {
44 Console.WriteLine(" !");
45 }
46 }
47
48 /// <summary>
49 /// ( )
50 /// </summary>
51 class Dog:Animal
52 {
53 string myName;
54 public Dog(string name): base(name)
55 {
56 myName = name;
57 }
58
59 /// <summary>
60 /// ( )
61 /// </summary>
62 public override string MyName
63 {
64 get { return " : , :"+this.name; }
65
66 }
67
68
69 /// <summary>
70 /// ( )
71 /// </summary>
72 public override void Eat()
73 {
74 Console.WriteLine(" !");
75 }
76
77 /// <summary>
78 /// ( )
79 /// </summary>
80 public override void Shout()
81 {
82 Console.WriteLine(" ! ! !");
83 }
84 }
85 /// <summary>
86 /// ( )
87 /// </summary>
88 class Cat : Animal
89 {
90 string myName;
91 public Cat(string name)
92 : base(name)
93 {
94 myName = name;
95 }
96 /// <summary>
97 /// ( )
98 /// </summary>
99 public override string MyName
100 {
101 get { return " : , :" + this.name; }
102
103 }
104
105 /// <summary>
106 /// ( )
107 /// </summary>
108 public override void Eat()
109 {
110 Console.WriteLine(" !");
111 }
112
113 /// <summary>
114 /// ( )
115 /// </summary>
116 public override void Shout()
117 {
118 Console.WriteLine(" ! ! !");
119 }
120 }
121
122 /// <summary>
123 /// ( )
124 /// </summary>
125 class Sheep : Animal
126 {
127 string myName;
128 public Sheep(string name)
129 : base(name)
130 {
131 myName = name;
132 }
133 /// <summary>
134 /// ( )
135 /// </summary>
136 public override string MyName
137 {
138 get { return " : , :" + this.name; }
139
140 }
141
142 /// <summary>
143 /// ( )
144 /// </summary>
145 public override void Eat()
146 {
147 Console.WriteLine(" !");
148 }
149
150 /// <summary>
151 /// ( )
152 /// </summary>
153 public override void Shout()
154 {
155 Console.WriteLine(" ! ! !");
156 }
157 }
//
Animal dog = new Dog(" ");
string myName=dog.MyName;
Console.WriteLine(myName);
dog.Eat();
dog.Shout();
// :
: , :
!
! ! !
//
Animal sheep = new Sheep(" ");
string myName = sheep.MyName;
Console.WriteLine(myName);
sheep.Eat();
sheep.Shout();
// :
: , :
!
! ! !
書き換え(new)
new:オーバーライドとは、異なるクラス(ベースクラスまたは派生クラス)に2つ以上の戻りタイプ、メソッド名、パラメータが同じであるが、メソッド体が異なるメソッドを指す.ただし、このオーバーライドは表面上のオーバーライドであるため、非表示とも呼ばれ、オーバーライドされた親メソッドは呼び出すことができる.
次の例で説明します.コードは次のとおりです.
1 /// <summary>
2 /// ( )
3 /// </summary>
4 class Animal
5 {
6 /// <summary>
7 ///
8 /// :
9 /// </summary>
10 protected string name;
11
12
13 /// <summary>
14 ///
15 /// </summary>
16 /// <param name="name"></param>
17 public Animal(string name)
18 {
19 this.name=name;
20 }
21
22 /// <summary>
23 /// ( )
24 /// </summary>
25 public virtual string MyName
26 {
27 get { return this.name; }
28
29 }
30
31 /// <summary>
32 /// ( )
33 /// </summary>
34 public virtual void Eat()
35 {
36 Console.WriteLine(" !");
37 }
38
39 /// <summary>
40 /// ( )
41 /// </summary>
42 public virtual void Shout()
43 {
44 Console.WriteLine(" !");
45 }
46 }
47
48 /// <summary>
49 /// ( )
50 /// </summary>
51 class Dog:Animal
52 {
53 string myName;
54 public Dog(string name): base(name)
55 {
56 myName = name;
57 }
58 /// <summary>
59 /// ( )
60 /// </summary>
61 public override string MyName
62 {
63 get { return " : , :"+this.name; }
64 }
65
66 /// <summary>
67 /// ( )
68 /// </summary>
69 new public void Eat()
70 {
71 Console.WriteLine(" !");
72 }
73
74 /// <summary>
75 /// ( )
76 /// </summary>
77 public new void Shout()
78 {
79 Console.WriteLine(" ! ! !");
80 }
81 }
//
Animal dog = new Dog(" ");
string myName=dog.MyName;
Console.WriteLine(myName);
dog.Eat();
dog.Shout();
// :
: , :
!
!
次のように呼び出し方法を変更します.
//
Dog dog = new Dog(" ");
string myName=dog.MyName;
Console.WriteLine(myName);
dog.Eat();
dog.Shout();
// :
: , : !
!
! ! !
派生クラスDogのEat()メソッドがnew修飾を使用する場合,DogのオブジェクトがAnimalオブジェクトに変換された後,AnimalクラスのEat()メソッドが呼び出されることが分かる.実際には,newキーワードを用いた場合,DogにおけるEat()メソッドとAnimalにおけるEat()メソッドとは無関係の2つのメソッドとなるが,それらの名前はたまたま同じであると理解できる.したがって、AnimalクラスのEat()メソッドは、使用されていないかvirtual修飾されていないか、アクセス権がどうであれ、ないかにかかわらず、DogのEat()メソッドには影響しません(newキーワードが使用されているため、DogクラスがAnimalクラスからEat()メソッドを継承していない場合、コンパイラは警告を出力します).
これは設計者が意図的に設計したものだと思います.私たちは時々このような効果を達成しなければならないからです.厳密にはnewを用いて多態を実現するとは言えず,特定の場合にたまたま多態の効果を実現したとしか言いようがない.
3.3要点:
a.マルチステートはオブジェクト向けの重要な特性の一つであり、同じ操作が異なるオブジェクトに作用し、異なる解釈があり、異なる実行結果を生成することができることを指す.
b.マルチステートは2種類に分けられる:1つはコンパイル時のマルチステートであり、リロードを用いて実現する.もう1つは、実行時のマルチステートであり、書き換えを使用して実現される.
c.書き換えにはoverrideキーワードとnewキーワードの2種類がある
d.new書き換えは実際には親メソッドの非表示であり,上書きされた親メソッドを呼び出すことができる.したがってnewは、書き換える(または非表示)親メソッドを虚メソッドまたは抽象メソッドとして定義する必要はありません.ただし、親メソッドが虚メソッドまたは抽象メソッドの場合、親メソッドが上書きされ、そうでない場合は非表示になります.
e.リロードとオーバーライドの発生条件:リロードは、必然的に1つのクラスで発生し、関数名が同じで、パラメータタイプまたは順序が異なることでリロードを構成し、戻りタイプとは関係なく書き換えが発生し、必然的にベースクラスと派生クラスで発生し、そのクラス関数はvirtualで修飾され、派生クラスはoverrideで修飾され、サブクラスにベースクラスと同じ名前(パラメータが異なる)の非虚関数を書く.ベースクラスの関数が非表示になり、コンパイル後にNewキーワードnew修飾の使用を求めるメッセージが表示されます.
非表示、子クラスでnewで親を非表示にする方法
f.new上書きと書き換え、リロードの違い:
子と親のパラメータが異なる場合
ベースクラス関数が虚関数でない場合、ベースクラス関数は非表示になります.(サブクラスとベースクラスは同じ範囲ではないので、リロードではありません)
ベースクラス関数が虚関数である場合、ベースクラス関数は非表示になります.(サブクラスとベースクラスが同じ範囲にないため、リロードではありません;パラメータが異なるため書き換えではありません)
子と親のパラメータが同じ場合
ベースクラス関数が虚関数でない場合、ベースクラス関数は非表示になります.(サブクラスとベースクラスは同じ範囲ではないので、リロードではありません.ベースクラスは虚関数ではないので、非表示で書き換えではありません)
ベースクラス関数が虚関数である場合、ベースクラス関数は上書きされます.(サブクラスとベースクラスは同じ範囲ではないので、リロードではありません)
==============================================================================================
ディレクトリに戻る<もしあなたに役に立つならば、覚えていて推薦して、分からない地方あるいは書くのが間違っている地方があって、多く交流してください>
==============================================================================================