microsoft visual c# .net 入門
Post on 23-Jan-2016
50 Views
Preview:
DESCRIPTION
TRANSCRIPT
Microsoft Visual C# .NET 入門
蘇慶隆clsu@mail.cjcu.edu.tw
2007/3/8 2
大綱1. C# 的創立與歷史2. 變數與資料型態3. 程式控制流程4. 陣列與字串5. 封裝、多型與繼承
2007/3/8 3
大綱1.1. C# C# 的創立與歷史的創立與歷史2. 變數與資料型態3. 程式控制流程4. 陣列與字串5. 封裝、多型與繼承
2007/3/8 4
C# 的創立與歷史近代物件導向程式設計C# 的創立何謂 .NET Framework ?C# 與 .NET Framework 的關係
2007/3/8 5
C# 的創立與歷史近代物件導向程式設計近代物件導向程式設計C# 的創立何謂 .NET Framework ?C# 與 .NET Framework 的關係
2007/3/8 6
近代物件導向程式設計C 語言的創立表示近代程式設計的開端
源於 1960 年代之結構化程式設計問世於 1970 年代, 1980 年代被廣泛使用程式碼在 5000 行左右就會有其維護上的困難
C++ 本質上是物件導向版本的 C 語言問世於 1979 年,由 Bjarne Stroustrup 設計1990 年代後被廣泛使用
2007/3/8 7
近代物件導向程式設計 - 續Java 是建立跨平台、可移植程式碼
問世於 1991 年,由 James Gosling 為主設計對於電腦環境的改變進行革新於 1994 年網際網路興盛而受到矚目
2007/3/8 8
C# 的創立與歷史近代物件導向程式設計C# C# 的創立的創立何謂 .NET Framework ?C# 與 .NET Framework 的關係
2007/3/8 9
C# 的創立C# 提出元件導向語言、跨語言溝通
由 Microsoft 所創立,為 Microsoft .NET 一部份問世於 2000 年,由 Anders Hejlsberg 為主設計Anders 為世界知名電腦語言專家,曾在 1980年代開發最快的 Pascal 編譯器,並成功將 Pascal 從 Dos 移植到 Windows 。
2007/3/8 10
C# 族譜
C
C++
Java C#
2007/3/8 11
C# 的創立與歷史近代物件導向程式設計C# 的創立何謂 何謂 .NET Framework.NET Framework ??C# 與 .NET Framework 的關係
2007/3/8 12
何謂 .NET Framework ?定義一共通語言執行環境( Common Language Runtime , CLR ),
管理程式執行狀態。.NET 類別函式庫,讓支援 .NET 的程式語言可以使用 CLR 進行操作。
2007/3/8 13
C# 的創立與歷史近代物件導向程式設計C# 的創立何謂 .NET Framework ?C# C# 與 與 .NET Framework.NET Framework 的關係的關係
2007/3/8 14
C# 與 .NET Framework 的關係
C# 最初由 Microsoft 所主導,用來建立 .NET Framework 的程式碼。C# 使用 .NET Framework 定義的函式庫。因此兩者之間是不可區分的,意味著學習C# 語法同時需了解使用 .NET Framework函式庫。
2007/3/8 15
大綱1. C# 的創立與歷史2.2. 變數與資料型態變數與資料型態3. 程式控制流程4. 陣列與字串5. 封裝、多型與繼承
2007/3/8 16
Hello World
using System;
class HelloWorld {
public static void Main() {
Console.WriteLine("Hello World C#.");
}
}
2007/3/8 17
Hello World – 續
2007/3/8 18
變數與資料型態數值型別參考型別變數宣告變數有效範圍運算子
2007/3/8 19
變數與資料型態數值型別數值型別參考型別變數宣告變數有效範圍運算子
2007/3/8 20
數值型別型別 說明 位元 範圍bool 表示真假值 1 { true, false }
byte 8 位元無號整數 8 0~255
char 字元 16 0~65535
decimal 針對金融計算設計 128 1e-28~7.9e+28
double 雙精準浮點數 64 5e-324~1.7e+308
float 單精準浮點數 32 5e-45~3.4e+38
int 整數 32 -2^31~2^31-1
2007/3/8 21
數值型別 - 續型別 說明 位元 範圍long 長整數 64 -2^63~2^63-1
sbyte 8 位元有號整數 8 -128~127
short 短整數 16 -32768~32767
uint 無正負號整數 32 0~2^32-1
ulong 無正負號長整數 64 0~2^64-1
ushort 無正負號短整數 16 0~65535
2007/3/8 22
變數與資料型態數值型別參考型別參考型別變數宣告變數有效範圍運算子
2007/3/8 23
參考型別參考型別為類別定義,稍候會詳細說明。參考型別即為 C/C++ 指標概念,為不可修改的固定指標。所有數值型別皆有別於參考型別,屬於基本資料型別。
2007/3/8 24
變數與資料型態數值型別參考型別變數宣告變數宣告變數有效範圍運算子
2007/3/8 25
變數宣告// 變數原型宣告type var-name;
// 初始化變數原型宣告type var-name=value;
// 動態初始化變數原型宣告type var-name=function-call();
2007/3/8 26
變數宣告 - 續using System;class Sample2_1 {
public static void Main() {int var1; // 變數宣告int var2 = 10; // 初始化變數宣告float f = 1.2f;double s1 = 3.0;double s12 = Math.Sqrt( s1 ); // 動態初始化變
數}
}
2007/3/8 27
變數與資料型態數值型別參考型別變數宣告變數有效範圍變數有效範圍運算子
2007/3/8 28
變數有效範圍class Sample2_2 {
public static void Main() {int var1 = 5;{
int var2 = 10;}var1 = 6;// var2 = 11; // 外層區塊無法看到內層區塊變數
}}
2007/3/8 29
變數有效範圍 - 續class Sample2_3 {
public static void Main() {
int var1 = 5;
{
var1 = var1 + 10;
}
var1 = var1 + 10; // 此時變數 var1 = 25
}
}
2007/3/8 30
變數與資料型態數值型別參考型別變數宣告變數有效範圍運算子運算子
2007/3/8 31
運算子算術運算子關係 / 邏輯運算子指派運算子三元運算子
2007/3/8 32
運算子算術運算子算術運算子關係 / 邏輯運算子指派運算子三元運算子
2007/3/8 33
算術運算子運算子 意義
+ 加法- 減法(也是單元負號)* 乘法/ 除法
% 除法取餘數++ 遞增-- 遞減
2007/3/8 34
算術運算子 - 續using System;class Sample2_4 {
public static void Main() {int iresult , i=25;double dresult, d;d = i + 9.2;iresult = i * 18;dresult = d / i;iresult++;Console.WriteLine("iresult = " + iresult);Console.WriteLine("dresult = " + dresult);
}}
2007/3/8 35
算術運算子 - 續
2007/3/8 36
運算子算術運算子關係關係 // 邏輯運算子邏輯運算子指派運算子三元運算子
2007/3/8 37
關係運算子運算子 意義
== 等於!= 不等於> 大於< 小於
>= 大於或等於<= 小於或等於
2007/3/8 38
邏輯運算子運算子 意義
& AND
| OR
^ XOR ( exclusive )|| Short-circuit OR
&& Short-circuit AND
! NOT
2007/3/8 39
布林真值表p q p & q p | q p ^ q !p
False False False False False True
True False False True True False
False True False True True True
True True True True False False
2007/3/8 40
關係 / 邏輯運算子 - 續using System;class Sample2_5{ public static void Main() { int i = 22, j = 23; bool b1 = true, b2 = false; Console.WriteLine("i < j " + (i < j)); Console.WriteLine("i != j " + (i != j)); Console.WriteLine("i > j " + (i > j)); Console.WriteLine("b1 & b2 " + (b1 & b2)); Console.WriteLine("b1 | b2 " + (b1 | b2)); Console.WriteLine("b1 ^ b2 " + (b1 ^ b2)); }}
2007/3/8 41
關係 / 邏輯運算子 - 續
2007/3/8 42
運算子算術運算子關係 / 邏輯運算子指派運算子指派運算子三元運算子
2007/3/8 43
指派運算子// 指派運算子原型宣告var-name = expression;expression 可以是任何合法的運算式,其意義是將等號右邊運算式結果指定給等號左邊運算元例如:int i = 5; // i = 5int j = i + 3; // j = 8int a = Math.Sqrt(10); // a = 100i = j = a; // i = j = a = 100a = a + 10; // a = 110
2007/3/8 44
複合指派// 複合指派運算子原型宣告var-name operator= expression;
operator 為任何需要二個運算元的運算子,例如:int a = 100;
a += 10; // 同義 a = a + 10, a = 110
a *= 10; // 同義 a = a * 10, a = 1100
a %= 10; // 同義 a = a % 10, a = 0
2007/3/8 45
運算子算術運算子關係 / 邏輯運算子指派運算子三元運算子三元運算子
2007/3/8 46
三元運算子// 三元運算子原型宣告expression1 ? expression2 : expression3;
expression1限定是 bool 運算式,意義為若 expression1 為真時,求 expression2 , 若 expression1 為假時,求 expression3 。例如:int a = -50;
int b = a < 0 ? -a : a; // b = 50
2007/3/8 47
運算子優先權
最高
最低
運算子! + (正號) - (負號) ++ --
* / %
+ (加法) - (減法)< > <= >=
= = !=
&
^
|
&&
||
? :
= op=
2007/3/8 48
大綱1. C# 的創立與歷史2. 變數與資料型態3.3. 程式控制流程程式控制流程4. 陣列與字串5. 封裝、多型與繼承
2007/3/8 49
程式控制流程選擇述句迭代述句跳躍述句
2007/3/8 50
程式控制流程選擇述句選擇述句迭代述句跳躍述句
2007/3/8 51
選擇述句if-else
if-else-if
switch
巢狀 switch
2007/3/8 52
選擇述句if-elseif-else
if-else-if
switch
巢狀 switch
2007/3/8 53
if-else
// if-else 原型宣告if(condition)
{
statement;
}
else
{
statement;
}
2007/3/8 54
if-else - 續using System;class Sample3_1 { public static void Main() { int i = 50, j = 123; i = i + j; j = j - i; if (i > j)
{ Console.WriteLine("i 大於 j " + (i - j)); } else { Console.WriteLine("i 小於 j " + (j - i)); } }}
2007/3/8 55
if-else - 續
2007/3/8 56
選擇述句if-else
if-else-ifif-else-if
switch
巢狀 switch
2007/3/8 57
if-else-if// if-else-if 原型宣告 1if(condition1){
statement1;}else if(condition2){
statement2;}...else{
statement3;}
// if-else-if 原型宣告 2if(condition1){
statement1;}else{
if(condition2){
statement2;}else{
statement3;}
}
2007/3/8 58
if-else-if – 續// Sample3_2
int factor = 60;if (factor % 2 == 0) { Console.WriteLine("60 最小因數為 2");}else if(factor % 3 == 0) { Console.WriteLine("60 最小因數為 3");}else if (factor % 5 == 0) { Console.WriteLine("60 最小因數為 5");}else { Console.WriteLine("60 沒有因數 { 2, 3, 5 }");}
2007/3/8 59
if-else-if – 續
2007/3/8 60
選擇述句if-else
if-else-if
switchswitch
巢狀 switch
2007/3/8 61
switch
// switch 原型宣告switch(expression) {
case constant1: statement1;break;
case constant2:statement2;break;
default:statement;break;
}
2007/3/8 62
switch - 續// Sample3_3
int a = 9;switch (a){ case 0: Console.WriteLine("a = 0"); break; case 1: Console.WriteLine("a = 1"); break; case 2: Console.WriteLine("a = 2"); break; case 3: Console.WriteLine("a = 3"); break; case 4: Console.WriteLine("a = 4"); break; default: Console.WriteLine("a > 4"); break;}
2007/3/8 63
switch – 續
2007/3/8 64
選擇述句if-else
if-else-if
switch
巢狀巢狀 switchswitch
2007/3/8 65
巢狀 switch
// 巢狀 switch 原型宣告switch(expression1) {
case constant1: statement1; break;
case constant2:
switch(expression2) {
case constant3: statement2; break;
case constant4: statement3; break;
default: statement4 break;
}
default: statement5; break;
}
2007/3/8 66
程式控制流程選擇述句迭代述句迭代述句跳躍述句
2007/3/8 67
迭代述句for
通常用於有限次數的迴圈while
通常用於未知次數或狀態判定的無窮迴圈do-while
通常用於至少執行一次的迴圈
2007/3/8 68
迭代述句forfor
while
do-while
2007/3/8 69
for
// for 原型宣告for(initialization; condition; iteration)
{
statement;
}
initialization 為迴圈初始狀態,設定迴圈控制變數condition 為 bool 運算式,判斷是否重覆進行迴圈iteration 定義每一次迴圈執行完改變控制變數的數量
2007/3/8 70
for - 續using System;class Sample3_4{ public static void Main() { int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } Console.WriteLine("1 + 2 + 3 + ... + 100 = " + sum); }}
2007/3/8 71
for - 續
2007/3/8 72
迭代述句for
whilewhile
do-while
2007/3/8 73
while
// while 原型宣告while(condition)
{
statement;
}
condition 為 bool 運算式,判斷是否重覆進行迴圈
2007/3/8 74
while - 續using System;class Sample3_5{ public static void Main() { int num = 123456789; int mag = 0; Console.WriteLine("Number: " + num); while (num > 0) { mag++; num /= 10; } Console.WriteLine("Magnitude: " + mag); }}
2007/3/8 75
while - 續
2007/3/8 76
迭代述句for
while
do-whiledo-while
2007/3/8 77
do-while
// do-while 原型宣告do
{
statement;
} while(condition);
condition 為 bool 運算式,判斷是否重覆進行迴圈
2007/3/8 78
do-while - 續// Sample3_6
int num = 128;int two = 0;
Console.WriteLine("Number: " + num);do{ if (num % 2 == 0) {
two++; } num /= 2; } while (num > 0);Console.WriteLine(" 共有 " + two + " 個 2 的因數 ");
2007/3/8 79
do-while - 續
2007/3/8 80
程式控制流程選擇述句迭代述句跳躍述句跳躍述句
2007/3/8 81
跳躍述句break
立即跳離迴圈continue
立即進入下一次迴圈條件判斷goto
無條件跳躍
2007/3/8 82
跳躍述句breakbreak
continue
goto
2007/3/8 83
breakusing System;class Sample3_7{ public static void Main() { for (int i = -10; i < 10; i++) { if (i > 0) { break;break; // 當 i 為正數時,終止迴圈 } Console.WriteLine(i); } }}
2007/3/8 84
break - 續
2007/3/8 85
跳躍述句break
continuecontinue
goto
2007/3/8 86
continueusing System;class Sample3_8{ public static void Main() { for (int i = 0; i < 100; i++) { if (i % 2 != 0) { continue;continue; } Console.Write(i + "\t"); } }}
2007/3/8 87
continue - 續
2007/3/8 88
跳躍述句break
continue
gotogoto
2007/3/8 89
gotousing System;class Sample3_9 { public static void Main() { for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) { Console.WriteLine(“(i, j, k)=(" + i + ", " + j + ", " + k + “)"); } if (j == 2) { goto goto exitexit;; } } } exitexit:: }}
2007/3/8 90
goto - 續
2007/3/8 91
大綱1. C# 的創立與歷史2. 變數與資料型態3. 程式控制流程4.4. 陣列與字串陣列與字串5. 封裝、多型與繼承
2007/3/8 92
陣列與字串陣列簡介一維陣列多維陣列迭代陣列字串簡介建構字串字串的運算
2007/3/8 93
陣列與字串陣列簡介陣列簡介一維陣列多維陣列迭代陣列字串簡介建構字串字串的運算
2007/3/8 94
陣列簡介陣列( Array )是相同型別的變數所形成的集合。陣列在 C# 被實作成物件的形式,但用法與 C/C++相似。陣列索引元素編號從零開始。陣列在程式設計中常用於資料處理,如:學生成績平均、歷年氣溫統計等。
2007/3/8 95
陣列與字串陣列簡介一維陣列一維陣列多維陣列迭代陣列字串簡介建構字串字串的運算
2007/3/8 96
一維陣列// 一維陣列原型宣告type[] array-name = new type[n];
所有陣列都必需使用 new 運算子進行記憶體配置。
// 初始化一維陣列原型宣告type[] array-name = { val, val2, val3, …, valN };
2007/3/8 97
using System;class Sample4_1{ public static void Main() { int[] sample1 = new int[10]; // 宣告一維整數陣列 int[] sample2 = { 5, 4, 3, 2, 1 }; // 初始化一維一整陣列
for (int i = 0; i < 10; i++) { sample1[i] = i+i; } }}
一維陣列 - 續
0 2 4 6 8 10 12 14 16 18
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
sample1 陣列示意圖
2007/3/8 98
陣列與字串陣列簡介一維陣列多維陣列多維陣列迭代陣列字串簡介建構字串字串的運算
2007/3/8 99
多維陣列// 多維陣列原型宣告type[,… ,] array-name = new type[n1, n2, … , nm];
// 初始化多維陣列原型宣告type[,… ,] array-name = { { val, val, val, …, val }
{ val, val, val, …, val }
…
{ val, val, val, …, val }
};
2007/3/8 100
using System;class Sample4_2{ public static void Main() { int[,] sample = new int[3, 4]; // 宣告二維整數陣列
for (int j = 0; j < 3; j++) { for (int i = 0; i < 4; i++) { sample[j, i] = (j * 4) + i + 1; } } }}
多維陣列 - 續
12111092
87651
43210
3210
sample 陣列示意圖j
isample[2,1]
2007/3/8 101
陣列與字串陣列簡介一維陣列多維陣列迭代陣列迭代陣列字串簡介建構字串字串的運算
2007/3/8 102
迭代陣列// 迭代陣列原型宣告foreach(type var-name in collection)
{
statement;
}
任何實作 .NET Framework 定義之集合(即 collection ),即可使用 foreach 迭代;陣列為實作集合之物件。經由迭代之集合不可在 statement 內進行修改。
2007/3/8 103
迭代陣列 - 續using System;class Sample4_3 { public static void Main() { int[] num = new int[20]; int sum = 0; for (int i = 0; i < 20; i++) { num[i] = i + 1; } foreach (int x in num)foreach (int x in num) { { sum += x;sum += x; }} Console.WriteLine("總和 : " + sum); }}
2007/3/8 104
陣列與字串陣列簡介一維陣列多維陣列迭代陣列字串簡介字串簡介建構字串字串的運算
2007/3/8 105
字串簡介在許多程式語言中,字串就是字元陣列,但 C# 並不採用此作法。字串在 C# 中為參考型別 string ,是唯一不需要使用 new 運算子初始化的物件。
2007/3/8 106
陣列與字串陣列簡介一維陣列多維陣列迭代陣列字串簡介建構字串建構字串字串的運算
2007/3/8 107
建構字串using System;class Sample4_4{ public static void Main() { // 建構初始化字串 string str = "In C#, strings are objects."; Console.WriteLine(str); }}
2007/3/8 108
建構字串 - 續
2007/3/8 109
陣列與字串陣列簡介一維陣列多維陣列迭代陣列字串簡介建構字串字串的運算字串的運算
2007/3/8 110
字串的運算// Sample4_5
string str1 = "C# 是 .NET 程式設計的首選語言 ";string str2 = "C# 的字串處理非常強大 ";string str3 = str2; string str3 = str2; // // 字串拷貝字串拷貝string str4 = str1 + ", " + str2;string str4 = str1 + ", " + str2; // // 字串連接字串連接if (str2 == str3) if (str2 == str3) // // 字串比較字串比較{ Console.WriteLine("str2 == str3");}else { Console.WriteLine("str2 != str3");}Console.WriteLine("str1 = " + str1); Console.WriteLine("str2 = " + str2);Console.WriteLine("str3 = " + str3); Console.WriteLine("str4 = " + str4);
2007/3/8 111
字串的運算 - 續
2007/3/8 112
大綱1. C# 的創立與歷史2. 變數與資料型態3. 程式控制流程4. 陣列與字串5.5. 封裝、多型與繼承封裝、多型與繼承
2007/3/8 113
封裝、多型與繼承封裝利用類別( class )的概念來說明如何建構物件( object ),因此稱物件是類別的實體( instance )。
多型類別可定義同名方法,只要參數宣告不同,此作法稱為方法重載( overloaded )。
繼承允許類別繼承( inheritance )其它類別的宣告內容,而進行衍生。
2007/3/8 114
封裝、多型與繼承封裝封裝多型繼承
2007/3/8 115
封裝定義類別建立物件建構式垃圾收集和解構式this 關鍵字存取修飾子方法參數
2007/3/8 116
封裝定義類別定義類別建立物件建構式垃圾收集和解構式this 關鍵字存取修飾子方法參數
2007/3/8 117
定義類別類別( class )是邏輯上的抽象概念,描述真實世界中物體的狀態和行為。例如:人的類別,可用描述人的年齡、身高、體重、血型等資料,和人會生氣、飢餓、跑步、蹲下等行為。在物件導向程式設計中,使用類別描述物體,類別的欄位( field )描述物體的狀態,類別的方法( method )描述物體的行為;其中欄位和方法統稱類別的成員( member )。
2007/3/8 118
定義類別 - 續// 類別原型宣告class classname {
access type field1;access type field2;// …access type fieldN;access return-type method1([parameters]) { /*…*/ }access return-type method2([parameters]) { /*…*/ }// …access return-type methodN([parameters]) { /*…*/ }
}
access 為存取修飾子type 為欄位型別field 為欄位名稱
2007/3/8 119
定義類別 - 續// 方法原型宣告access return-type method([type param1, type param2, …,
type paramN])
{
// 方法本體// …
}
access 為存取修飾子type 為參數型別param 為參數名稱
2007/3/8 120
定義類別 - 續// Sample5_1 例如:定義「人」的類別class Person {
public string Name;public int Tallness;public int Weight;public int Age;public void Walk() {
Console.WriteLine(" 行走 " + ((Tallness / Weight) / 2) + " 公尺 ");}public void Resume() {
Console.WriteLine("姓名 : " + Name); Console.WriteLine("身高 : " + Tallness); Console.WriteLine("體重 : " + Weight); Console.WriteLine(" 年齡 : " + Age);
}}
2007/3/8 121
封裝定義類別建立物件建立物件建構式垃圾收集和解構式this 關鍵字存取修飾子方法參數
2007/3/8 122
建立物件當類別定義完成後,使用 new 運算子動態產生類別的實體,即配置物件的記憶體。物件即是真實世界中的物體,例如:人、汽車、電腦,不同的物體有其自身的狀態和行為。當將實體化物件時,需指定一個參考型別(即變數),不同的物件其參考亦不相同。設定物件的欄位使用「 .」運算子進行存取。
2007/3/8 123
建立物件 - 續// Sample5_2 建立「人」的物件class Sample5_2
{
public static void Main()
{
Person cuteofdragon = new Person(); // 建立 Person 物件 /* 同義如下: Person cuteofdragon; // 宣告物件的參考 cuteofdragon = new Person();// 配置 Person 物件 */
}
}
2007/3/8 124
建立物件 - 續// Sample5_2 建立「人」的物件class Sample5_2
{
public static void Main()
{
Person person = new Person(); // 建立 Person 物件// 設定物件欄位person.Name = "王大明 ";
person.Tallness = 180;
person.Weight = 65;
person.Age = 23;
}
}
2007/3/8 125
封裝定義類別建立物件建構式建構式垃圾收集和解構式this 關鍵字存取修飾子方法參數
2007/3/8 126
建構式建構式是和類別名稱同名的方法,但沒有回傳值型態。當物件實體化前,就會呼叫類別建構式。在建構式中要確保初始化所有定義之欄位,典型作法是透過參數建構式進行初始化。所有類別都具有建構式,沒有明確指定時會自動提供預設的建構式,將所有欄位設為零或 null 。
2007/3/8 127
建構式 - 續// 類別建構式原型宣告class classname {
access classname([parameters])
{
}
}
parameters 表示零個或多個參數
2007/3/8 128
建構式 - 續class Person { public Person() { Name = "未知 "; Tallness = 0; Weight = 0; Age = -1; } public Person(string name, int tallness, int weight, int age) { Name = name; Tallness = tallness; Weight = weight; Age = age; }}
2007/3/8 129
封裝定義類別建立物件建構式垃圾收集和解構式垃圾收集和解構式this 關鍵字存取修飾子方法參數
2007/3/8 130
垃圾收集和解構式在 C# ,使用 new 運算子產生的物件不需手動釋放記憶體(像 C++ 使用 delete 運算子),而是採用自動垃圾收集機制。垃圾收集是自動回收沒有再被參考的物件,執行時機無法明確知道,由系統決定。不可依賴垃圾收集進行重要執行程式的依據。解構式是和類別名稱同名的方法,差別在於同名方法前面加上「 ~」。解構式沒有存取方式、回傳值和傳入參數。
2007/3/8 131
垃圾收集和解構式 - 續解構式在垃圾收集前會先呼叫,就如同建構式在實體化物件時相同。解構式呼叫時機亦無法確定,所以不可依賴執行重要的程式碼。物件在離開變數有效範圍後不會呼叫解構式。明確指定呼叫垃圾收集亦不能保證可回收物件的解構式會立即執行。程式結束前保證會呼叫所有執行時期產生物件的解構式,但執行順序無法保證(並非堆疊)。
2007/3/8 132
垃圾收集和解構式 - 續// 類別解構式建構式原型宣告class classname {
~classname()
{
}
}
2007/3/8 133
垃圾收集和解構式 - 續class Person{ public Person(string name, int tallness, int weight, int age) { Name = name; Tallness = tallness; Weight = weight; Age = age; }
~Person()~Person() {{ Console.WriteLine("Console.WriteLine("摧毀摧毀 : " + Name);: " + Name); }}}
2007/3/8 134
垃圾收集和解構式 - 續class Sample5_4{ public static void Main() { Person person; for (int i = 0; i < 10000; i++) { person = new Person(i.ToString(), 100 + i % 100, 50 + i % 50, i % 100); } }}
2007/3/8 135
垃圾收集和解構式 - 續
2007/3/8 136
封裝定義類別建立物件建構式垃圾收集和解構式this this 關鍵字關鍵字存取修飾子方法參數
2007/3/8 137
this 關鍵字this 是當任何物件進行方法呼叫時會隱含傳入叫用的物件參考。this 的主要用途是當方法傳入引數和類別欄位變數名稱相同時,此時引數會遮蔽類別欄位,因此 this 可指定使用類別欄位。
2007/3/8 138
this 關鍵字 - 續class Person { public Person(string Name, int Tallness, int Weight, int Age) { this.Name = Name;this.Name = Name; this.Tallness = Tallness;this.Tallness = Tallness; this.Weight = Weight;this.Weight = Weight; this.Age = Age;this.Age = Age; }
public void Resume() { Console.WriteLine("姓名 : " + Name); Console.WriteLine("身高 : " + Tallness); Console.WriteLine("體重 : " + Weight); Console.WriteLine("年齡 : " + Age); }}
2007/3/8 139
this 關鍵字 - 續using System;
class Sample5_5{ public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); Person person2 = new Person("李小葉 ", 165, 56, 20);
person1.Resume(); person2.Resume();
}}
2007/3/8 140
this 關鍵字 - 續
2007/3/8 141
封裝定義類別建立物件建構式垃圾收集和解構式this 關鍵字存取修飾子存取修飾子方法參數
2007/3/8 142
存取修飾子指定類別成員存取修飾子是物件導向程式設計重要的具體實作,用來控制類別成員的存取權。本質上類別成員可分為公開級( public )和私有級( private )。存取修飾子正確的指定後,私有級的成員即可阻隔該類別外的所有存取,建立「黑盒子」概念的運作模式。
2007/3/8 143
存取修飾子 - 續修飾子等級 說明
public 類別成員可在所有程式碼存取。
private類別成員只可被定義之類別方法存取。不指定的預設類別成員屬於此等級。
protected類別成員可被定義之類別及其繼承之類別存取。
internal 類別成員只可被該組件之內存取。
protected internal類別成員只可被該組件之內或繼承之類別存取。
2007/3/8 144
存取修飾子 - 續存取修飾子指導方針:1. 只在該類別出現的成員應為私有級。2. 若成員具有範圍限制應為私有級,並提供公
開級方法進行存取。3. 若成員改變後會影響本身物件應為私有級。4. 用來設定私有級成員的方法應為公開級。5. 當成員沒有設定為私有級理由時,則可設定
為公開級。
2007/3/8 145
class Person { public string Name; public int Tallness; // 指定公開級 public int Weight; private int age; // 明確指定私有級 int healthiness; // 預設私有級,範圍
0~100
public Person() { Name = "未知 "; Tallness = 0; Weight = 0; age = -1; healthiness = 100; }
public Person(string name, int tallness, int weight, int age) { this.Name = name; this.Tallness = tallness; this.Weight = weight; SetAge(age); }
~Person() { Console.WriteLine("摧毀 : " + Name); }
public void SetAge(int age) { this.age = age; healthiness = 100 - age; healthiness = healthiness < 0 ? 0 :
healthiness; }
public int GetAge() { return age; }
public int GetHealthiness() { return healthiness; }
public void Walk() { Console.WriteLine(" 行走 " + ((Tallness / Weight) / 2) + " 公尺 "); }
public void Resume() { Console.WriteLine("姓名 : " + Name); Console.WriteLine("身高 : " + Tallness); Console.WriteLine("體重 : " + Weight); Console.WriteLine("年齡 : " + age); Console.WriteLine("健康 : " + healthiness); }}
2007/3/8 146
using System;class Sample5_6{ public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); person1.Resume();
person1.SetAge(40); Console.WriteLine("目前健康狀態 : " + person1.GetHealthiness());
// 不能這樣存取 age //person1.age = 60;
person1.Tallness = 178; person1.Weight = 73;
person1.Resume();
}}
2007/3/8 147
存取修飾子 - 續
2007/3/8 148
封裝定義類別建立物件建構式垃圾收集和解構式this 關鍵字存取修飾子方法參數方法參數
2007/3/8 149
方法參數物件傳給方法使用 ref
使用 out
使用 params
回傳物件
2007/3/8 150
方法參數物件傳給方法物件傳給方法使用 ref
使用 out
使用 params
回傳物件
2007/3/8 151
物件傳給方法在呼叫方法傳入引數時,除了可傳入數值型態之外,也可傳入參考型態。任何物件(定義為 class 且不是內定基本型態)傳入方法時,皆以參考型態傳入。當物件傳入方法後,物件參考即為固定,變更物件參考只會作用該方法,不會影響物件在呼叫方法時的參考。
2007/3/8 152
class Person { // … public bool IsEqual(Person obj) { if (obj.Name == this.Name && obj.Tallness == this.Tallness && obj.Weight == this.Weight && obj.age == this.age) return true; else return false; }
// …}
class Sample5_7 { public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); Person person2 = new Person("李小葉 ", 165, 56, 20); if (person1.IsEqual(person2))if (person1.IsEqual(person2)) Console.WriteLine("person1 == person2"); else Console.WriteLine("person1 != person2"); }}
2007/3/8 153
物件傳給方法 - 續
2007/3/8 154
方法參數物件傳給方法使用 使用 refref
使用 out
使用 params
回傳物件
2007/3/8 155
使用 ref
方法參數分為傳值呼叫( call-by-value )和傳參考呼叫( call-by-reference )。預設方法呼叫使用傳值呼叫。在方法參數型別前加上 ref 標示表示欲傳入之型別以傳參考呼叫,表示參數在方法內進行變更後,會影響呼叫方法的引數。若參數標示 ref 時,參數必需已經初始化。當進行方法呼叫時,需回傳兩個以上的值可以 ref 處理。
2007/3/8 156
class Person { // …
public static void SwapVal(Person p1, Person p2) { Person tmp; tmp = p1; p1 = p2; p2 = tmp; }
public static void SwapRef(ref Person p1, ref Person p2) { Person tmp; tmp = p1; p1 = p2; p2 = tmp; }
// …}
2007/3/8 157
using System;class Sample5_8 { public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); Person person2 = new Person("李小葉 ", 165, 56, 20);
Console.WriteLine(" 傳值呼叫交換前 ..."); person1.Resume(); person2.Resume(); Person.SwapVal(person1, person2); // 傳值呼叫 Console.WriteLine("傳值呼叫交換後。 "); person1.Resume(); person2.Resume(); Person.SwapRef(ref person1, ref person2); Person.SwapRef(ref person1, ref person2); // // 傳參考呼叫傳參考呼叫 Console.WriteLine("傳址呼叫交換後。 "); person1.Resume(); person2.Resume(); }}
2007/3/8 158
使用
ref -
續
2007/3/8 159
方法參數物件傳給方法使用 ref
使用 使用 outout
使用 params
回傳物件
2007/3/8 160
使用 out
out 參數標示類似 ref ,差異只在 out 參數標示不需要初始化,且在方法回傳前必須完成初始化或指定。
2007/3/8 161
class Person { // … public void Copy(out Person duplicatePerson) { duplicatePerson = new Person(); duplicatePerson.Name = this.Name; duplicatePerson.Tallness = this.Tallness; duplicatePerson.Weight = this.Weight; duplicatePerson.age = this.age; duplicatePerson.healthiness = this.healthiness; }
// …}
class Sample5_9 { public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); Person person2;Person person2; person1.Copy(out person2);person1.Copy(out person2); person1.Resume(); person2.Resume(); }}
2007/3/8 162
使用 out - 續
2007/3/8 163
方法參數物件傳給方法使用 ref
使用 out
使用 使用 paramsparams
回傳物件
2007/3/8 164
使用 params
通常方法參數個數可預先知道,但若是同型別的參數個數未知時,可用 params 參數標示。params 為一同型別之陣列,使用時須在參數型別後面加上 [ ] ,因此參數本身不能為陣列宣告;若同型別之物件皆為陣列,則使用泛型物件 object 。方法參數只能使用一個 params 參數標示,且必須為最後一個參數宣告。
2007/3/8 165
using System;
class Sample5_10 { public static int Min(params int[] nums)public static int Min(params int[] nums) { int min = Int32.MaxValue; foreach (int n in nums) { if (n < min)
min = n; } return min; } public static void Main() { Random rnd = new Random(); int[] nums = new int[100]; for (int i = 0; i < 100; i++) { nums[i] = rnd.Next(0, 10000); Console.Write(nums[i] + "\t"); } int min = Min(nums); Console.WriteLine("\n最小值 : " + min); }}
2007/3/8 166
使用 params - 續
2007/3/8 167
方法參數物件傳給方法使用 ref
使用 out
使用 params
回傳物件回傳物件
2007/3/8 168
回傳物件方法可以回傳任何型別,像是基本型別的整數,或是類別型別的物件。在方法使用 new 運算子產生的區域變數物件可作為回傳物件。
2007/3/8 169
class Person { // … public Person Clone() { Person person = new Person(); person.Name = this.Name; person.Tallness = this.Tallness; person.Weight = this.Weight; person.age = this.age; person.healthiness = this.healthiness; return person;return person; }
// …}class Sample5_11 { public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); Person person2 = person1.Clone(); person1.Resume(); person2.Resume(); }}
2007/3/8 170
回傳物件 - 續
2007/3/8 171
封裝、多型與繼承封裝多型多型繼承
2007/3/8 172
多型方法重載建構式重載運算子重載
2007/3/8 173
多型方法重載方法重載建構式重載運算子重載
2007/3/8 174
方法重載方法重載( method overloading )是物件導向程式設計中實作多型的方式之一。在 C# ,同一類別中可存在一個以上同名方法,而只要方法參數中宣告型別或參數個數不同即可。若同名方法只有回傳型別不同是不合法的。參數標示( ref 和 out )視為不同的方法參數宣告,但 params 同等於陣列宣告。方法重載的概念是為了實作不同型別但具有相同行為的程式碼,即是「一個介面、多個方法」,透過共同的方法名稱的存取來達到。
2007/3/8 175
class Sample5_12 { public static int Min(params int[] nums)public static int Min(params int[] nums) { int min = Int32.MaxValue; foreach (int n in nums) { if (n < min) min = n; } return min; } public static double Min(params double[] nums)public static double Min(params double[] nums) { double min = Double.MaxValue; foreach (double n in nums) { if (n < min) min = n; } return min; }
// …}
2007/3/8 176
using System;
class Sample5_12 { public static void Main() { Random rnd = new Random(); // 隨機產生亂數類別 int[] nums1 = new int[100]; double[] nums2 = new double[100]; for (int i = 0; i < 100; i++) { nums1[i] = rnd.Next(0, 10000); Console.Write(nums1[i] + "\t"); } for (int i = 0; i < 100; i++) { nums2[i] = rnd.NextDouble() * 100; Console.Write(nums2[i].ToString("f2") + "\t"); } int min1 = Min(nums1);int min1 = Min(nums1); double min2 = Min(nums2);double min2 = Min(nums2); Console.WriteLine("\nnum1 最小值 : " + min1); Console.WriteLine("num2 最小值 : " + min2); }}
2007/3/8 177
方法重載 - 續
2007/3/8 178
多型方法重載建構式重載建構式重載運算子重載
2007/3/8 179
建構式重載建構式重載能夠以不同的方式建構物件。建構式重載常用於允許某個物件初始化 / 建構另一個物件。使用 this 關鍵字可呼叫重載的建構式。建構式重載的概念在於執行時期動態建構物件或是延遲物件某些欄位初始化。
2007/3/8 180
class Person { public Person()public Person() { Name = "未知 "; Tallness = 0; Weight = 0; age = -1; healthiness = 100; } public Person(string name) : this(name, 0, 0, 0)public Person(string name) : this(name, 0, 0, 0) { } public Person(string name, int tallness, int weight, int age)public Person(string name, int tallness, int weight, int age) { this.Name = name; this.Tallness = tallness; this.Weight = weight; SetAge(age); }}
2007/3/8 181
using System;
class Sample5_13{ public static void Main() { Person person1 = new Person("王大明 ", 180, 65, 23); Person person2 = new Person("李小葉 "); Person person3 = new Person();
person1.Resume(); person2.Resume(); person3.Resume(); }}
2007/3/8 182
建構式重載 - 續
2007/3/8 183
多型方法重載建構式重載運算子重載運算子重載
2007/3/8 184
運算子重載將自訂的類別型態賦予運算符號,使得物件和物件可以進行運算,稱為運算子重載。如果有一自訂類別命名為「二維座標」,若重載「 +」運算子,則( 3, 5 ) + ( 4, -3 ) = ( 7, 2 )
2007/3/8 185
運算子重載 - 續// 重載一元運算子原型宣告public static return-type operator op(type operand)
{
// statement;
}
// 重載二元運算子原型宣告public static return-type operator op(type operand1, type operand2)
{
// statement;
}
2007/3/8 186
class Coordinate { int x; int y;
public Coordinate() {
}
public Coordinate(int x, int y) { this.x = x; this.y = y; }
public int GetX() { return x; } public void SetX(int x) { this.x = x; } public int GetY() { return y; } public void SetY(int y) { this.y = y; }
// …}
2007/3/8 187
運算子重載 - 續重載一元運算子重載二元運算子重載關係運算子重載布林判斷重載邏輯運算子
2007/3/8 188
運算子重載 - 續重載一元運算子重載一元運算子重載二元運算子重載關係運算子重載布林判斷重載邏輯運算子
2007/3/8 189
// 重載一元運算子 public static Coordinate operator ++operator ++(Coordinate op1) { op1.x++; op1.y++; return op1; }
public static Coordinate operator --operator --(Coordinate op1) { op1.x--; op1.y--; return op1; }
2007/3/8 190
運算子重載 - 續重載一元運算子重載二元運算子重載二元運算子重載關係運算子重載布林判斷重載邏輯運算子
2007/3/8 191
// 重載二元運算子 public static Coordinate operator +operator +(Coordinate op1, Coordinate op2) { Coordinate result = new Coordinate(); result.x = op1.x + op2.x; result.y = op1.y + op2.y; return result; }
public static Coordinate operator +operator +(Coordinate op1, int op2) { Coordinate result = new Coordinate(); result.x = op1.x + op2; result.y = op1.y + op2; return result; }
public static Coordinate operator *operator *(Coordinate op1, Coordinate op2) { Coordinate result = new Coordinate(); result.x = op1.x * op2.x; result.y = op1.y * op2.y; return result; }
2007/3/8 192
運算子重載 - 續重載一元運算子重載二元運算子重載關係運算子重載關係運算子重載布林判斷重載邏輯運算子
2007/3/8 193
// 重載關係運算子 public static bool operator >operator >(Coordinate op1, Coordinate op2) { if (op1.x > op2.x && op1.y > op2.y) { return true; } else { return false; } }
public static bool operator <operator <(Coordinate op1, Coordinate op2) { if (op1.x < op2.x && op1.y < op2.y) { return true; } else { return false; } }
2007/3/8 194
public static bool operator ==operator ==(Coordinate op1, Coordinate op2) { if (op1.x == op2.x && op1.y == op2.y) { return true; } else { return false; } }
public static bool operator !=operator !=(Coordinate op1, Coordinate op2) { if (op1.x != op2.x && op1.y != op2.y) { return true; } else { return false; } }
2007/3/8 195
運算子重載 - 續重載一元運算子重載二元運算子重載關係運算子重載布林判斷重載布林判斷重載邏輯運算子
2007/3/8 196
// 重載布林判斷 public static bool operator trueoperator true(Coordinate op1) { if (op1.x != 0 || op1.y != 0) { return true; } else { return false; } }
public static bool operator falseoperator false(Coordinate op1) { if (op1.x == 0 && op1.y == 0) { return true; } else { return false; } }
2007/3/8 197
運算子重載 - 續重載一元運算子重載二元運算子重載關係運算子重載布林判斷重載邏輯運算子重載邏輯運算子
2007/3/8 198
// 重載邏輯運算子 public static bool operator !operator !(Coordinate op1) { if (op1.x != 0 && op1.y != 0) { return false; } else { return true; } }
public static bool operator &operator &(Coordinate op1, Coordinate op2) { if ((op1.x != 0 && op1.y != 0) & (op2.x != 0 && op2.y != 0)) { return true; } else { return false; } }
2007/3/8 199
using System;class Sample5_14{ public static void Main() { Coordinate c0 = new Coordinate(0, 0); Coordinate c1 = new Coordinate(3, 5); Coordinate c2 = new Coordinate(4, -3);
Coordinate c3 = c1 + c2; Coordinate c4 = c1 - c2; Coordinate c5 = c1 * c2; Coordinate c6 = c1 / c2;
Coordinate c7 = c1++; Coordinate c8 = c2--;
bool b1 = c7 > c8; bool b2 = c6 <= c2;
// … }}
2007/3/8 200
using System;class Sample5_14{ public static void Main() {
// … if (c4)
Console.WriteLine("c4 至少有一個座標不為零。 "); else Console.WriteLine("c4 所有座標都為零。 ");
if(!c5) Console.WriteLine("c5 所有座標都為零。 "); else Console.WriteLine("c5 至少有一個座標不為零。 ");
if(c3 & c4) Console.WriteLine("c3 和 c4 兩個座標都不為零。 ");
if(c7 | c0) Console.WriteLine("c7 和 c1 至少有一個座標不為零。 "); }}
2007/3/8 201
重載一元運算子 - 續
2007/3/8 202
封裝、多型與繼承封裝多型繼承繼承
2007/3/8 203
繼承繼承原理成員名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 204
繼承繼承原理繼承原理成員名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 205
繼承原理繼承( inheritance )是物件導向程式建立階層類別的基礎。被繼承的類別稱為基礎類別或父類別,繼續的類別稱為衍生類別或子類別。透過繼承可為相同性質的類別建立共同的功能,再為各個類別定義特別的功能。衍生類別可繼承基礎類別定義的欄位、方法、屬性、運算子和索引器。
2007/3/8 206
繼承原理 - 續衍生類別必須明確定義其擁有的建構式,衍生類別建構式使用 base 關鍵字建構其基礎類別部份。實體化衍生類別物件只允許呼叫衍生類別建構式。衍生類別允許存取 protected 級但不允許存取基礎類別 private 修飾字的欄位或方法。
2007/3/8 207
繼承原理 - 續// 繼承基礎類別原型宣告class derived-classname : base-classname{
// 呼叫基礎類別建構式derived-classname([parameters1]) : base([parameters2]){
// 衍生類別建構式本體}// 定義衍生類別本體// …
}
parameters 表示零個或多個參數parameters1 和 parameters2 可為不同各數之參數
2007/3/8 208
class Asian : Personclass Asian : Person { string country; public Asian() : base(): base() { } public Asian(string name, int tallness, int weight, int age, string country) : base(name, tallness, weight, age): base(name, tallness, weight, age) { this.country = country; } public void ShowCountry() { Console.WriteLine(Name + " 所在國家為 " + country); }}class American : Person: Person { public string state; public American() : base(): base() { } public American(string name, int tallness, int weight, int age, string state) : base(name, tallness, weight, age): base(name, tallness, weight, age) { this.state = state; } public void ShowState() { Console.WriteLine(Name + " 所在州為 " + state); }}
2007/3/8 209
using System;
class Sample5_15{ public static void Main() { Asian asianPerson = new Asian("王大明 ", 180, 65, 23, "台灣 "); American americanPerson = new American("李小葉 ", 165, 56, 20, "紐約 ");
asianPerson.ShowCountry(); americanPerson.ShowState();
Console.ReadLine(); }}
2007/3/8 210
繼承原理 - 續
2007/3/8 211
繼承繼承原理欄位名稱遮蔽欄位名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 212
欄位名稱遮蔽衍生類別欄位 /方法與基礎類別欄位 /方法名稱相同時,預設基本類別欄位 /方法名稱會被遮蔽;在衍生類別欄位 /方法名稱前加上 new 修飾子作為明確遮蔽區別。被遮蔽的類別欄位 /方法,使用 base 關鍵字可存取基本類別欄位名稱。
2007/3/8 213
class Asian : Person {
string country;
new string Name;new string Name; // 此欄位遮蔽了 Person 類別的 Name
public Asian(string name, int tallness, int weight, int age, string country)
: base(name, tallness, weight, age) {
this.Name = "this.Name = " 亞洲人 亞洲人 - " + name;- " + name;
this.country = country;
}
// 此方法遮蔽了 Person 類別的 Resume()
public new void Resume()public new void Resume() {
Console.WriteLine("[Person] Console.WriteLine("[Person] 姓名姓名 : " + base.Name);: " + base.Name);
Console.WriteLine("[Asian] 姓名 : " + Name);
Console.WriteLine("身高 : " + Tallness);
Console.WriteLine("體重 : " + Weight);
Console.WriteLine("年齡 : " + age);
Console.WriteLine("健康 : " + healthiness);
Console.WriteLine("國家 : " + country);
}
}
2007/3/8 214
using System;
class Sample5_16
{
public static void Main()
{
Asian asianPerson = new Asian("王大明 ", 180, 65, 23, "台灣 ");
asianPerson.Resume();
}
}
2007/3/8 215
欄位名稱遮蔽 - 續
2007/3/8 216
繼承繼承原理欄位名稱遮蔽建立階層體系建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 217
建立階層體系類別階層體系可衍生一個以上類別,衍生的類別保有所有基礎類別的功能。在 C# 中,只允許單一繼承的類別階層體系,多重繼承概念則使用介面實現。多重繼承的類別階層體系容易造成階層體系操作混亂及不易控制。
2007/3/8 218
class Taiwanese : Asian
{
public string Region;
public Taiwanese() : base()
{ }
public Taiwanese(string name, int tallness, int weight, int age, string
country, string region)
: base(name, tallness, weight, age, country)
{
this.Region = region;
}
public void ShowRegion()
{
Console.WriteLine(base.Name + " 所在區域為 " + Region);
}
}
2007/3/8 219
using System;
class Sample5_17{ public static void Main() { Taiwanese taiwanese1 = new Taiwanese("王大明 ", 180, 65, 23, "台灣 ", "台南 ");
taiwanese1.Resume(); taiwanese1.Walk(); taiwanese1.ShowRegion(); }}
2007/3/8 220
建立階層體系 - 續
2007/3/8 221
繼承繼承原理欄位名稱遮蔽建立階層體系建構式呼叫順序建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 222
建構式呼叫順序在類別階層體系中,建構式呼叫順序從最上層基礎類別開始往下層衍生類別呼叫。如 A 類別為基礎類別, B 類別繼承 A , C類別繼承 B ,建構 C 物件時,建構式呼叫順序為 A->B->C 。類別建構式使用 base 時,依據給定參數選擇上層基礎類別,若未使用 base 時,使用預設無參數上層基礎類別建構式。
2007/3/8 223
class A{ int _a; public A() { Console.WriteLine(" 建構 A 物件。 "); }
public A(int _a) { this._a = _a; Console.WriteLine(" 建構 A 物件,傳入一個參數。 "); }
public override string ToString() { return "_a = " + _a + "\n"; }}
2007/3/8 224
class B : A{ int _b; public B() { Console.WriteLine(" 建構 B 物件。 "); } public B(int _b) { this._b = _b; Console.WriteLine(" 建構 B 物件,傳入一個參數。 "); } public B(int _a, int _b) : base(_a) { this._b = _b; Console.WriteLine(" 建構 B 物件,傳入二個參數。 "); } public override string ToString() { return base.ToString() + "_b = " + _b + "\n"; }}
2007/3/8 225
class C : B { int _c; public C() { Console.WriteLine(" 建構 C 物件。 "); } public C(int _c) { this._c = _c; Console.WriteLine(" 建構 C 物件,傳入一個參數。 "); } public C(int _a, int _b, int _c) : base(_a, _b) { this._c = _c; Console.WriteLine(" 建構 C 物件,傳入三個參數。 "); } public override string ToString() {
return base.ToString() + "_c = " + _c; }}
2007/3/8 226
using System;
class Sample5_18
{
public static void Main()
{
C c = new C(123, 456, 789);
Console.WriteLine(c.ToString());
}
}
2007/3/8 227
建構式呼叫順序 - 續
2007/3/8 228
繼承繼承原理欄位名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 229
基礎與衍生型別轉換在 C# 強型別特性中,不同的參考型別變數無法指定給另一參考型別變數。基礎類別的參考變數可以參考衍生類別的參考變數,亦即衍生類別的參考變數可以指定給基礎類別的參考變數,指定後,基礎類別的參考變數只能處理本身的類別欄位和方法;注意,反之不成立。
2007/3/8 230
using System;
class Sample5_19
{
public static void Main()
{
A a = new A(1);
B b = new B(2, 3);
C c = new C(456, 789, 101112);
// 正確,基礎類別參考衍生類別變數 a = b;
// 錯誤,衍生類別不可參考基礎類別變數 //c = b;
}
}
2007/3/8 231
繼承繼承原理欄位名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 232
虛擬方法虛擬方法( virtual method )是類別方法,在方法宣告中加上 virtual 修飾子。當類別方法宣告為虛擬方法時,表示其衍生類別重載同名方法可擁有各自版本的方法。重載方法使用 override 修飾子,當重載虛擬方法時,方法型別簽署和回傳值須完全相同。在執行時期呼叫的虛擬方法由物件參考的型別決定,即所謂的動態方法分派,是實作多型重要的功能。虛擬方法宣告不能為 static 或 abstract 。
2007/3/8 233
虛擬方法 - 續虛擬方法的應用在於定義一般性的基礎類別方法,讓所有衍生類別方法重載。結合繼承和虛擬方法,在類別階層體系可透過相同名稱的方法呼叫方式操作物件,並可實作相容介面和擴充再衍生的類別,實現「一個介面,多個方法」物件導向多型的重要功能。
2007/3/8 234
class A {
// …
public virtualvirtual void CallVirtualMetohd() {
Console.WriteLine("Call Virtual Metohd: A");
}
// …
}
class B : A {
// …
public overrideoverride void CallVirtualMetohd() {
Console.WriteLine("Call Virtual Metohd: B");
}
// …
}
2007/3/8 235
using System;
class Sample5_20{ public static void Main() { A a = new A(1); B b = new B(2, 3); C c = new C(456, 789, 101112);
a.CallVirtualMetohd(); a = b; a.CallVirtualMetohd(); a = c;a = c; a.CallVirtualMetohd(); }}
2007/3/8 236
虛擬方法 - 續
2007/3/8 237
繼承繼承原理欄位名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別抽象類別避免繼承泛型物件裝箱與拆箱
2007/3/8 238
抽象類別抽象類別( abstract class )定義抽象方法,即不提供實作的方法。在類別和方法宣告加上 abstract 修飾字。衍生類別必須明確實作由抽象類別定義的抽象方法。virtual 和 abstract 修飾字不可同時使用。
2007/3/8 239
抽象類別 - 續// 抽象類別原型宣告abstract class classname{
// …abstract return-type method([parameters]);// …
}
parameters 表示零個或多個參數
2007/3/8 240
abstract abstract class Person{
// … public abstract abstract void Resume();}
class Asian : Person{ // … public overrideoverride void Resume() { Console.WriteLine("[Person] 姓名 : " + base.Name); Console.WriteLine("[Asian] 姓名 : " + Name); Console.WriteLine("身高 : " + Tallness); Console.WriteLine("體重 : " + Weight); Console.WriteLine(" 年齡 : " + age); Console.WriteLine("健康 : " + healthiness); Console.WriteLine("國家 : " + Country); Console.WriteLine(); }}
2007/3/8 241
using System;
class Sample5_21{ public static void Main() { Taiwanese taiwanese1 = new Taiwanese("王大明 ", 180, 65, 23, " 台灣 ", " 台南 ");
taiwanese1.Resume(); }}
2007/3/8 242
繼承繼承原理欄位名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承避免繼承泛型物件裝箱與拆箱
2007/3/8 243
避免繼承在類別宣告加上 sealed ,任何其它類別將不可繼承。避免繼承的類別常用於需要特定初始化設定的類別或不希望類別擴充功能。
2007/3/8 244
避免繼承 - 續// 避兔繼承類別原型宣告sealed class classname{
// …// 類別定義
}
2007/3/8 245
繼承繼承原理欄位名稱遮蔽建立階層體系建構式呼叫順序基礎與衍生型別轉換虛擬方法抽象類別避免繼承泛型物件裝箱與拆箱泛型物件裝箱與拆箱
2007/3/8 246
泛型物件裝箱與拆箱C# 定義一特殊類別 object ,所有類別都默認繼承 object (包含數值基本型別),稱為泛型型別。當泛型參考變數重新指向時會進行裝箱( boxing ),反之進行拆箱。當拆箱時要確保泛型參考可正確轉型,並要明確指定轉型類別名稱。
2007/3/8 247
using System;class Sample5_22 { public static void Main() { object obj; Person p; Taiwanese t1 = new Taiwanese("王大明 ", 180, 65, 23, " 台灣 ", " 台南 "); Taiwanese t2; obj = t1; // 將 t1 裝箱到 obj t2 = (Taiwanese) obj; // 將 obj 拆箱到 t2 // 延伸思考 ... p = t1; t1 = (Taiwanese)p; p = t1; t2 = t1; obj = t2; p = (Person)obj; Console.WriteLine(obj.ToString()); Console.WriteLine(p.ToString()); Console.WriteLine(t1.ToString()); Console.WriteLine(t2.ToString()); }}
2007/3/8 248
泛型物件裝箱與拆箱 - 續
top related