C#OOP之四 深入理解方法(cctv5體育節目表)
視頻:https://edu.csdn.net/course/detail/27107
方法深入研究
方法是完成特定功能的代碼集。舉例來類比一下,比如一臺電視,我們開啟電視開關之后,我們不需要去理解電視是如何選臺、和電視臺聯系上而播放的步驟,只需要知道會開關電視、選臺等就可以了。所以,方法就象一個被封閉的起來的功能操作。
訪問修飾符
封裝就是使某些信息隱藏起來,但是,對于一定范圍的信息仍是可見的。
封裝是面向對象三大特性之一。主要是為了一.避免非法數據的訪問;二.保證數據的完整性。
我們可以通過訪問修飾符來實現封裝。C#支持以下如下訪問修飾符:
訪問修飾符是一些關鍵字,用于指定聲明的成員或類型的可訪問性。
【世間萬物皆有一定的存在或活動范圍,比如你是中國人,那么你的活動范圍大部分在中國,如果你要去國外你就得辦個護照。再比如你是鄭州海洋館的一只熱帶魚,那么別人要來看你,至少要買張門票。世間萬物的這種活動和訪問范圍的機制使世界可以有條不紊的運作。對象或對象成員屬性和方法也需要通過某種機制來約束其訪問,所以就有了訪問修飾符這些東東。】
本節介紹四個訪問修飾符:
n????????public
n????????protected
n????????internal
n????????private
使用這些訪問修飾符可指定下列五個可訪問性級別:
聲明的可訪問性
含義
public
訪問不受限制。
protected
訪問僅限于包含類或從包含類派生的類型。
internal
訪問僅限于當前程序集。
protected internal
訪問僅限于從包含類派生的當前程序集或類型。
private
訪問僅限于包含類型。
切記前面有分號,表示分隔.
項目1:模擬CS游戲中警察的程序
項目背景:對于每位玩過第一人稱射擊類游戲的朋友來說,CS不能不被反復提起。我們以里面的警察為例,來學習一下訪問修飾符符的用處與區別。
解決方案:通過修改訪問修飾符,來觀察了解訪問修飾符的作用范圍。
任務1:編寫代碼,在UltraEdit中編寫如下代碼,并嘗試修改訪問修飾符。
/*
功能:實現一款游戲中的一個角色的定義
時間:2015/09/08
版本:1.0
*/
usingSystem;
classPolice
{
//屬性:Police的成員變量;
private int id; //private:私有的?何為私有:只能被類本身來訪問;
private string NickName; //昵稱
private string Clothes; //衣服
//行為:成員方法
public void SetInfo() //設置警察信息方法
{
id=888; //這些信息不應該放在Game類里,而應該由Police類的對象來操作;同樣訪問一個類的成員變量需要,使用對象.成員變量
NickName="菜青蟲";
Clothes="綠色迷彩服";
}
public void Display()
{
Console.WriteLine("Id:"+id+"昵稱:"+NickName+" 衣服:"+Clothes); //顯示一下信息
}
public void Pao() //成員方法定義:[訪問修飾符][返回類型]方法名(參數列表){方法代碼}
{
Console.WriteLine("跑@....");
}
public void Zou()
{
Console.WriteLine("走#....");
}
public void Sheji()
{
Console.WriteLine("射擊DDDDDD");
}
}
class Game
{
static void Main() //程序的入口處
{
Police kiki=newPolice();
//嘗試在此處直接訪問類的成員變量
//kiki.id=”007”;kiki.NickName=”金頭云”
kiki.SetInfo();
kiki.Display();
kiki.Pao(); //對象名.方法()
kiki.Zou();
kiki.Sheji();
Console.ReadLine();
}
}
2.選擇文件à保存,以保存該文件,并以Police.cs結束。
3.編譯并運行該程序。
4.觀察測試不同訪問修飾符的區別異同。
方法的定義
方法是類的組成元素,而方法本身又是由很多代碼組成的,這些代碼也可以包含對方法的調用。事實上,我們在前面的章節已經不止一次用過方法了,例如Main(),我們一直在使用這個方法。方法的定義包括
<訪問修飾符><返回類型> 方法名? (形式參數列表)
{
方法體
}
方法命名規則和變量名命名規則一樣,方法名應該反映對象行為的含義。
方法的參數列表表示方法接受的處理數據,很多時候事務的行為需要一定的處理數據行為才能正常執行。比如說洗衣機的處理數據是要洗的衣服,動物“吃”方法的處理數據是吃的東西等等。參數列表可以是以下形式:
void ?eat(); //空參數,不需要參數
void eat(string sPork); //一個形式參數sPork (簡稱形參)
void eat(string? sEgg,int ?iNum);? ?//兩個形式參數(sEgg,iNum)
void eat(string sEgg,int iNum,string?sAddress);//三個形式參數(sEgg,iNum,sAddress)"
方法調用:eat(“豬肉”) ??//注意在此處傳入的值”豬肉”為實際參數(簡稱實參)
方法體指要在方法中執行的代碼,它是該方法的詳細處理步驟。比如洗衣機的“洗衣”方法里面就包括詳細洗衣的步驟,比如左轉20圈然后右轉20圈、洗衣20分鐘、甩干等。
返回類型用關鍵字return,return語句使用時重點要注意以下幾個問題:
n???????一個方法中可以出現多個return語句,但只有一個會被執行;
n???????返回值的數據類型必須與方法定義返回值數據類型相同;
n???????如果方法定義了返回值則必須使用return語句進行返回;
n???????當遇到return語句時,方法執行將終止,執行被中斷并退出方法;
下面來看一下計算器的程序,看是否仍有需要提高的地方。
/*
功能:實現一個非常簡單的計算器,根據客戶的要求來進行+ - * /運算;
時間:2015/09/09 ;在第三章Demo\Switch基礎上完善
版本:2.1.3
*/
using System;
class Calc //Calc類完成的功能是什么?用戶輸入和計算;輸入應該放到客戶端來實現,但是此處留個小尾巴.到4.0擴展;
{
//1.成員變量
double x,y; //1.聲明兩個變量
char op; //op表示操作符; //注意比較:int、char、string的使用,使用哪個更好一些。
//2.成員方法
public void Shuru()
{
Console.WriteLine("請輸入第一個操作數:");
x=Convert.ToDouble(Console.ReadLine());
Console.WriteLine("請輸入第二個操作數:");
y=Convert.ToDouble(Console.ReadLine());
}
public void Jisuan()
{
Console.WriteLine("請輸入您要進行的運算:+ - * /");
op=Convert.ToChar(Console.ReadLine()); //因為op是char型的,需要強制轉換;
switch(op)
{
case '+':
Console.WriteLine("和為:"+(x+y));
break;
case '-':
Console.WriteLine("差為:"+(x-y));
break;
case '*':
Console.WriteLine("積為:"+(x*y));
break;
case '/':
if(y==0)
Console.WriteLine("除數不能為0");
else
Console.WriteLine("商為:"+(x/y));
break;
default:
Console.WriteLine("錯誤選擇:");
break;
}
}
}
//***************************************客戶端類
class CalcGUI
{
static void Main()
{
Calc jisuanqi=new Calc();
jisuanqi.Shuru();
jisuanqi.Jisuan();
}
}
該版本的計算器中已經很好的實現了,業務邏輯(計算功能)和界面(客戶端:輸入)的功能,但是依據OO的原則,應該具有良好的擴展性和復用性,如果在此時,需要增加新的功能則必須再次修改swich中的內容,并且輸出功能也應該在客戶端實現。因此,此程序仍有完善的必要。下面請大家做項目2,實現業務邏輯與客戶端分離的程序。
項目2:計算器:將計算功能和用戶輸入、輸出功能分離
項目背景:剖析計算器,更好的體會OO擴展性、復用性的好處。
解決方案:使用帶返回值的方法來解決.
任務1:編寫代碼
/*
功能:實現計算器;將計算功能和用戶輸入分離
時間:2015/09/09 星期二? 第二節課
版本:4.1.1
*/
usingSystem;
classCalc
{
//Calc類的成員變量x,y
private double x,y;
private double result; //再增加一個結果變量
public void ShuRu()
{
//在此接受x,y的值
Console.WriteLine("請輸入第一個操作數:");
x=Convert.ToDouble(Console.ReadLine());
Console.WriteLine("請輸入第二個操作數:");
y=Convert.ToDouble(Console.ReadLine());
}
public double Jia()
{
result=x+y;
return result;
}
public double Jian()
{
result=x-y;
return result;
}
public double Cheng()
{
result=x*y;
return result;
}
public double Chu()
{
if(y==0)
return 0; //注意此處是有問題的,考慮如何修改
else
{
result=x/y;
return result;
}
}
}
/**********客戶端類,即界面類***********/
classClacGUI
{
static void Main()
{
Calc jisuanqi; //jisuanqi=?
jisuanqi=new Calc();
jisuanqi.ShuRu();
Console.WriteLine(“和”+jisuanqi.Jia()); //返回double型的和-->數
Console.WriteLine(“差”+jisuanqi.Jian()); //返回double型的差-->數
Console.WriteLine(“積”+jisuanqi.Cheng()); //返回double型的積-->數
Console.WriteLine(“商”+jisuanqi.Chu()); //返回double型的商-->字符串
//doublex,y; //在Main()方法內,所以說不是ClacGUI的成員變量.叫什么呢?(考察的知識點,為變量的作用域)
}
}
任務2:保存程序為Calc4.cs,并編譯程序
任務3:運行程序Calc4
任務4:體會本程序與Calc3的區別,考慮改進在何處,是否仍有改進的余地。
任務5:擴充,使用沒有返回值的方法,使用返回類型為string的方法如何做?
項目3:計算器:使用帶參數的方法
項目背景:剖析計算器,更好的體會OO擴展性、復用性的好處。在原有計算器的基礎上增加求平方、求階乘的功能。
解決方案:使用帶返回值及帶參數的方法來解決.
任務1:編寫代碼
/*
功能:實現計算器;將計算功能和用戶輸入分離
時間:2015/09/09 星期二? 第二節課
版本:5.1.1
*/
usingSystem;
classCalc
{
private double result; //再增加一個結果變量
public double Jia(double num1,double num2) //加法運算:形參:num1,num2
{
result=num1+num2;
returnresult;
}
publicdouble Jian(double num1,double num2) //減法運算
{
result=num1-num2;
returnresult;
}
publicdouble Cheng(double num1,double num2) //乘法運算
{
result=num1*num2;
returnresult;
}
publicdouble Chu(double num1,double num2) //除法運算
{
result=num1/num2;
returnresult;
}
publicdouble PingFang(double num1)
{
result=num1*num1;
returnresult;
}
publicdouble NciFang(double num1,double num2) //num1:2的num2:5次方
{
result=1; //定義result為1
for(inti=1;i<=num2;i++)
{
result=result*num1;
}
return result;
}
}
/**********客戶端類,即界面類***********/
classClacGUI
{
static void Main()
{
Calc jisuanqi; //jisuanqi=?
jisuanqi=new Calc();
double x,y; //x,y為Main()的局部變量
Console.Write("請輸入第一個數字:");
x=Convert.ToDouble(Console.ReadLine());
Console.Write("請輸入第二個數字:");
y=Convert.ToDouble(Console.ReadLine());
char op; //op為Main()的局部變量,表示操作符
Console.Write("請輸入您要進行的運算:+ - * / ^:"); //^:表示求N次方
op=Convert.ToChar(Console.ReadLine());
switch(op)
{
case '+': //加運算
Console.WriteLine(jisuanqi.Jia(x,y));
break;
case '-':
Console.WriteLine(jisuanqi.Jian(x,y));
break;
case '*': //加運算
Console.WriteLine(jisuanqi.Cheng(x,y));
break;
case '/':
if(y==0)
Console.WriteLine("除數不能為0");
else
Console.WriteLine(jisuanqi.Chu(x,y));
break;
case '^':
Console.WriteLine(jisuanqi.NciFang(x,y));
break;
default:
Console.WriteLine("其他無效選擇!!!");
break;
}
}
}
任務2:保存文件,并編譯程序
任務3:運行程序
任務4:體會參數在方法中的應用。
方法參數:值參數、引用參數、輸出參數
值參數:聲明方法時,不帶任何修飾符號的是值參數,一個值參數相當于一個局部變量。當使用值參數時,將會分配一個新的存儲位置,將實參的值拷貝到這個位置,并且將此拷貝傳遞給該方法。允許方法將新值傳遞給值參數,但是這樣的賦值只影響實參的副本,而不影響在方法調用時由調用方法給出的實參。被調用方法不會修改內存中實參的值,所以,使用值參數時可以保證實參值是安全的。
簡而言之:值參數只能將值帶進方法,不能將值帶出方法。
案例:二數字交換
//NotSwap.cs
// 值參數不能影響實參的值
usingSystem;
classTest
{
static void NotSwap(int x, int y)
{
Console.WriteLine("進入NotSwap時:x = {0}, y = {1}", x, y);
int temp = x;
x = y;
y = temp;
Console.WriteLine("退出NotSwap時:x = {0}, y = {1}", x, y);
}
static void Main()
{
int i = 1, j = 2;
Console.WriteLine("執行NotSwap前:i = {0}, j = {1}", i, j);
NotSwap(i, j);
Console.WriteLine("執行NotSwap后:i = {0}, j = {1}", i, j);
}
}
程序運行效果是值參數的值僅僅在方法體內被改變,而不能影響對應的實參的值。
引用參數:
用ref修飾符聲明的參數是引用參數。與值參數不同,引用參數不能創建新的存儲位置,用參數表示的存儲位置就是在方法調用中,作為實際參數對應的變量所表示的存儲位置。
變量在作為引用參數傳遞之前,必須先明確賦值。
簡而言之:引用參數既能將值帶進方法,也能將值帶出方法。
案例:二數交換
//Swap.cs
// 引用參數會影響實參的值
usingSystem;
classTest
{
static void Swap(ref int x, ref int y)
{
Console.WriteLine("進入Swap時:x = {0}, y = {1}", x, y);
int temp = x;
x = y;
y = temp;
Console.WriteLine("退出Swap時:x = {0}, y = {1}", x, y);
}
static void Main()
{
int i = 1, j = 2;
Console.WriteLine("執行Swap前:i = {0}, j = {1}", i, j);
Swap(ref i, ref j);
Console.WriteLine("執行Swap后:i = {0}, j = {1}", i, j);
}
}
輸出參數:
用out修飾的參數是輸出參數,其他同ref參數一樣,在使用之前無須賦值,必須在方法內完成對象的初始化。
簡而言之:輸出參數不能將值帶進方法,只能將值帶出方法。
案例:將路徑分解為目錄名和文件名的方法SplitPath,需要返回目錄名和文件名兩個值。
//SplitPath.cs
// 利用輸出參數來返回多個值
usingSystem;
classTest
{
static void SplitPath(string path, outstring dir, out string name)
{
int i = path.Length;
while (i > 0)
{
char ch = path[i-1];
if (ch == '\' || ch == '/'|| ch == ':')
break;
i--;
}
dir = path.Substring(0, i);
name = path.Substring(i);
}
static void Main()
{
string dir, name;
SplitPath("c:\Windows\System\hello.txt",out dir, out name);
Console.WriteLine("目錄名: {0}",dir);
Console.WriteLine("文件名: {0}", name);
}
}
靜態方法與實例方法
static:用來修飾靜態成員和靜態方法;
沒有使用static修飾的成員和方法為實例成員和實例方法;
區別如下:
ü???????靜態成員、方法屬于類,被類的所有實例共享;實例成員、方法屬于對象(類的實例),每個對象都有實例成員的不同副本。
ü???????靜態成員只標識一個存儲位置,無論創建了多少個類的實例,它的靜態成員在內存中都只占同一塊區域;類的實例成員屬于類的實例所有,每創建一個類的實例,都在內存中為實例成員開辟一塊區域。
ü???????靜態成員、方法通過類名.運算符來使用;實例成員、方法通過對象名. 運算符來使用。
ü???????靜態方法只能訪問類中的靜態成員,而不能使用實例成員。
在前面的Console類的WriteLine、Write等方法就是靜態方法,是通過類Console來引用的。
案例:使用賬戶Account類獲取銀行信息的靜態方法PrintBankInfo
//Account2.cs
// 演示方法的聲明和調用
usingSystem;
classAccount
{
private decimal balance;
private string name;
public Account(string name)
{
this.balance = 0;
this.name = name;
Print("開戶", 0);
}
public bool Deposit(decimal amount)
{
if (amount <= 0)
return false;
balance += amount;
Print("存入", amount);
return true;
}
public bool Withdraw(decimal amount)
{
if (amount > balance || amount <=0)
return false;
balance -= amount;
Print("取出", amount);
return true;
}
private void Print(string operation,decimal amount)
{
Console.WriteLine("---------------------------");
Console.WriteLine("姓名: {0}", name);
Console.WriteLine("{0}: {1}",operation, amount);
Console.WriteLine("余額: {0}", balance);
Console.WriteLine("---------------------------");
}
public static void PrintBankInfo()
{
Console.WriteLine("---------------------------");
Console.WriteLine(" XYZ銀行, 電話: 12345678");
Console.WriteLine("---------------------------");
Console.WriteLine(" 顧客至上 服務第一 ");
Console.WriteLine("---------------------------");
}
public static void Main()
{
Account.PrintBankInfo();
Account acc = new Account("張三");
bool succeed = acc.Deposit(100);
if (!succeed)
Console.WriteLine("存款失敗!");
succeed = acc.Withdraw(37);
if (!succeed)
Console.WriteLine("取款失敗!");
}
}
有時候使用靜態方法非常方便。對于常用的“工具”方法一般都使用靜態方法啦實現,比如Math類。
實踐問題:
選擇題:
1.????? 說明以下語句是正確的還是錯誤的
封裝意味著防止訪問不需要的信息()
2.?????請注意以下語句
語句A :靜態變量即使在執行它們所屬的函數后仍然保持其原值。
語句B:靜態函數可以訪問靜態以及非靜態的變量。
以下那項是正確的?
a.A和B都正確
b.A正確,B錯誤
c.A 錯誤,B正確
d.A和B都是錯誤
3.判斷以下語句是正確的還是錯誤的:
在公共訪問區分符中,基類的所有公共成員都是受保護的。
抽象代表對象或類的基本特性,這些特性使得它們能夠與其他對象或類區別開來。
小結:
在本章中,我們主要學習了:
u??????訪問修飾符的分類和使用范圍
u??????參數化方法的幾種方式
u??????靜態方法和靜態變量
英語詞匯:
英文???????????? 全文????????????????????????????????????????中文
Public????????????????????????????????????????????????????? 公共的、公開的
Private???????????????????????????????????????????????????? 私有的
Protected??????????????????????????????????????????????? 受保護的
Internal???????????????????????????????????????????? 內部的
Access??????????????????????????????????????????????????? 訪問
Outside??????????????????????????????????????????? 外部的
Definition???????????????????????????????????????????????? 定義
Operator???????????????????????????????????????????????? 操作符
Model???????????????????????????????????????????????????? 模型
Set?????????????????????????????????????????????????? ?????? 設置
Get????????????????????????????????????????????????????????? 得到
Error????????????????????????????????????????????????????????????? 錯誤
Area?????????????????????????????????????????????????????????????? 區域
Specifier?? ??????????????????????????????????????????? ?????? 修飾符
Return??????????????????????????????????????????????????????????? 返回
Method?????????????????????????????????????????????????? 方法
Parameterparameter list????????????????????????? ????????????? 參數
List????????????????????????????????????????????????????????? 列表
Following?????????????????????????????????????????????????????? 下面的
Factorial??? ??????????????????????????????????????????????????????? 階乘
Out????????? ??????????????????????????????????????????????????????????????? 輸出的
Ref??reference??????????????????????????????????????????????????? 引用
Example????????????????????????????????????????????????? 例子
Count???????????????????????????????????????????????????????????? 計數
練習項目:
編寫一個程序,該程序要計算用戶輸入的數的階乘。請使用靜態和靜態變量創建此程序。提示:用戶輸入數的極限是1-20。
C# 面向對象編程
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。