C#之淺析面向物件程式設計思想(一)
縱觀MicroSoft公司的幾種主流語言,C是面向過程,VB既有面向過程也有面向物件的特性,而C#則是純粹的面向物件的程式語言。在UML的學習過程中,畫類圖、物件圖的時候面向物件的思想就已經用到了具體的學習中,而C#的學習過程中我們接著深入來學習這種思想,只不過這次是把OOP的思想用到了實際的程式碼程式設計之中。
我們知道面向物件的四個基本原則:抽象、封裝、模組化、層次性;面向物件思想的程式設計特性:繼承性、封裝性、多型性。通過楚老師的視訊,對面向物件的四個基本原則和程式設計特性都有了新的認識,這篇部落格就先對其中的部分特性進行分析。
一、靜態變數與非靜態變數
在上一篇部落格中,對C#基礎的分析是以“資料”引出來的,資料中變數在程式設計中佔有一席之地,那我們就從靜態變數和非靜態變數兩個角度對它進行分析。
using system; using system.Collections.Generic; using System.text namespace ConsoleApplication1 { class TestStatic { public static void main() { int k=AccessTest.x; //此處直接使用,如果不是靜態變數則寫成 AccessTest myOk = newAccessTest(); Console.WriteLine(k); AccessTest myOk=new AccessTest(); Cosole.WriteLine(myOK.y); //通過例項化才能訪問y } } public class AccessTest { public static int x=12; public int y=12; } }
由例子可知,在AccessTest類中定義了兩個變數x和y,其中x為靜態static,y為非靜態,在TestStatic類的Main函式如果要分別對AccessTest類中的x和y進行訪問,則對於x可以直接使用,而對於y需要首先例項化AccessTest類,然後再由該例項去呼叫其中的y。也就是說靜態變數中的成員可以通過類名直接進行訪問,而例項成員(非靜態變數)必須通過建立物件的引用來訪問(此處區別物件和物件引用,物件引用是一個地址而不是一個值)。我想如果x和y都定義成了非靜態變數的話,那樣程式碼量會大增的。
通過學習,對static變數有了自己的認識,但是理解的程度僅限於此,至於在程式碼中何處該用靜態變數,還有待於在以後的學習中去探索。
二、方法
所謂的方法,就是物件的行為,在之前學習VB的時候物件有屬性、事件和方法,而在真正面向物件的語言中沒有事件的概念,或者說事件就是屬於方法中的。
方法的句法如下:
[訪問修飾符] 返回值型別 <方法名> ([引數列表])//不需要返回值時用void
{
//方法主體
}
正如上面介紹的靜態變數和非靜態變數那樣,呼叫靜態的方法同樣無需進行例項化,而非靜態的方法需要進行類的例項化之後進行呼叫該方法。
方法可以被重複呼叫即“方法過載”在C#中是一個非常重要的定義,視訊中老師將其分為“具有不同數量引數的方法過載”和“對不同資料執行相似功能的方法過載”,如下:
Using System;
Namespace chognzai
{
Class Class1
{
Public int a,b;
Public double x,y;
Public int fun(int a,int b) //方法名稱相同,引數不同
{
Return a+b;
}
Public double fun(double x,double y) //方法名稱相同,引數不同
{
Return a+b;
}
Static void Main(string[] args)
{
Class1 sd=new Class1();
Sd.a=156;
Sd.b=32;
Sd.x=23.56;
Sd.y=56.49;
Console.WriteLine(“{0}+{1}={2}”,sd.a,sd.b,sd.fun(sd.a,sd.b));
Console.writeLine(“{0}+{1}={2}”,sd.x,sd.y,sd.fun(sd.x,sd.y));
Console.ReadLine();
}
}
}
該例子中成員函式fun()被過載,屬於“對不同資料執行相似功能的方法過載”,再次驗證了方法是可以多次使用的這個觀點。
三、屬性引發的封裝性的體現
先看個小例子,這是在視訊中非常經典的那個交電話費的例子。
namespace Customer
{
public enum TypeofCall
{
callToMobile,CallTOLandLine
}
class Program
{
static void Main(string[] args)
{
Customer tom=new Customer();
tom.CustomerName="楚廣明"; //設定屬性的值
tom.RecordCall(TypeofCall.callToMobile,20);
tom.RecordCall(TypeofCall.callToLandline,40);
Console.WriteLine("{0}有{1}電話費要交",tom.CustomerName,tom.customerBalance) //讀取屬性的值
}
}
public class Customer
{
private string name;
private decimal balance;
public string CustomerName //*****屬性****//
{
get( return name;)
set ( name=value;)
}
public decimal CustomerBalance //****屬性***//
{
get ( return balance;) //只能讀取餘額,而不能修改
}
public void RecordPayment(decimal amountpaid) //***方法*** //
{
balance-=amountpaid;
}
public void RecordCall(TypeofCall callType,uint nMinute) //***方法*** //
{
swistch(callType)
{
case TypeofCall.CallToLandline:
balance+=(0.02M*nMinutes);
break;
case TypeofCall.callToMobile:
balance+=(0.3M*nMinutes);
default:
break;
}
}
}
}
例子有點長,其中僅僅對屬性進行分析,就像:
public string CustomerName //*****屬性****//
{
get( return name;)
set ( name=value;)
}
public decimal CustomerBalance //****屬性***//
{
get ( return balance;) //只能讀取餘額,而不能修改
}
這兩個屬性是這個例子中的Customer類例項化後tom物件的兩個屬性,很明顯屬性區別於方法就像當初學習VB一樣,一個說明的是屬性,另一個說的是動作。從這個例子中還能體現出面向物件封裝性的思想,就像CustomerBalance屬性那樣,僅僅為讀取屬性,而沒有設定屬性的程式碼,這樣我們在主程式中就不能去修改,從而保護了隱私。也就是說通過屬性,將類的成員變數隔離,通過賦值、取值實現間隱藏封裝的功能,這也可以看做是一種許可權的限制。
通過這個小例子,OOP的封裝性也就是通過其他間接的手段去操作類的成員變數,不要讓別人知道你的成員變數中包含著什麼,當然這裡所謂的間接手段可以是上面所提到的屬性,也可以是方法,前提是該方法的訪問修飾符是public,通過該方法呼叫相同類中訪問修飾符為private的成員變數或者成員方法,從而實現封裝,在C#視訊中有個“訪問密碼的最短長度(private)”的例子就是通過這個方法實現的。
總結:
在C#中面向物件的思想嗎,目前僅僅是瞭解,需要急切去做的就是到《設計模式》的時候多去敲例子,多去回顧現在學的這些東西,帶著問題去學新知識,從而實現“溫故而知新”的效果。
在接下來的面向物件總結中將對“繼承、多型”做淺析,期待。