第九單元 面向對象一:類與對象

来源:https://www.cnblogs.com/xuyubing/archive/2023/05/30/17442885.html
-Advertisement-
Play Games

假設,班級里40位同學,我們用程式保存40位學生的信息:學號,姓名,性別,生日,身份證號。如果是你,你會怎麼實現? 小菜同學拿到這個題,奮書疾筆,馬上寫出如下代碼: ArrayList list = new ArrayList(); ​ string stuNo1="10001"; string n ...


假設,班級里40位同學,我們用程式保存40位學生的信息:學號,姓名,性別,生日,身份證號。如果是你,你會怎麼實現?

小菜同學拿到這個題,奮書疾筆,馬上寫出如下代碼:

ArrayList list = new ArrayList();
​
string stuNo1="10001";
string name1 = "張三";
string sex="男";
Datetime birthday1 = Datetime.Parse("1998-08-08");
string idCard1 = "362530199808080510";
list.add(stuNo1);
list.add(name1);
... list.add....
    
........//經過1個半小時後,終於到了第40位。

 

那如果是有4000,4萬?你是不是立馬從入門到卸載了?面向對象來告訴你解決方案!!

1. 面向對象概念

面向對象編程( OOP,Object Oriented Programming

  • 並不是一個技術,而是一種編程指導思想。

  • 把現實世界的具體事物全部看成一個一個的對象來解決實際問題。

為什麼要用面向對象編程

生活中我們解決問題就是按照對象化的方式進行的。如果程式也能夠按照生活的中的方式來解

決問題,那麼程式就更符合人類的思維習慣,代碼看起來會更易理解、更簡單、更易維護。

 

面向對象編程共同三大特性:封裝,繼承,多態。

在C# 中,一定要時刻的牢記這句話:一切皆為object(對象);

2. 封裝

封裝 被定義為"把一個或多個項目封閉在一個物理的或者邏輯的包中"。在面向對象程式設計方法論中,封裝是為了防止對實現細節的訪問。

抽象和封裝是面向對象程式設計的相關特性。抽象允許相關信息可視化,封裝則使開發者實現所需級別的抽象

訪問修飾符

C# 封裝根據具體的需要,設置使用者的訪問許可權,並通過 訪問修飾符 來實現。

一個 訪問修飾符 定義了一個類成員的範圍和可見性。C# 支持的訪問修飾符如下所示:

  • public:所有對象都可以訪問;

  • private:對象本身在對象內部可以訪問;

  • protected:只有該類對象及其子類對象可以訪問

  • internal:同一個程式集的對象可以訪問;

  • protected internal:訪問限於當前程式集或派生自包含類的類型。

img

實現封裝的方式共有三種:類的封裝,屬性封裝,方法的封裝。

封裝的作用:

  • 隱藏細節,設置訪問許可權,提高安全性

  • 代碼復用。

  • 提高代碼的可讀性

3. 什麼是類

類是一組具有相同事物和行為的抽象(物以類聚)。

類在實現生活中是不存在的,看不見,摸不著。例如:人類,狗類,貓科類,靈長類.... 這些事物都只是一些抽象的概念,並不是指具體的物體。如果我說:小明今天吃了三碗飯,小紅的頭髮很長,那麼,小明,小紅 是指人類的具體對象,lucky(一隻貓) 這個月身體長得很快,這也指的是對象,因為lucky是實實在在存在的。

人為什麼不和狗分為一類?

答:因為人和狗的體徵行為都不一樣!!再次強調類:類是一組具有相同事物和行為的抽象(物以類聚)。人會思考,人會製作工具,而狗不會。

 

對象:是真實存在的具體實例。

類(設計圖):是對象共同特征的描述(抽象)。

 

在C#中,必須先設計類,才能獲得對象。

 

4. 如何定義類

定義類的關鍵字是class,命名規範為首字母大寫,以帕斯卡(大駝峰)方式命名 如:

<訪問修飾符> class 類名
{
    // 構造器(下一個單元會講到)
    
    // 欄位
    
    // 屬性(特征)
    
    // 方法(行為)
    
    // 事件(C# 高級階段學習)
    
    // 索引器(c# 高級階段學習)
    
}

如:
public class Person
{
    // 欄位
    private string name;
    
    // 屬性
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            value=name;
        }
    }
    
    // 方法
    public void eat()
    {
        Console.WriteLine("吃飯,我要吃油燜大蝦");
    }
}

 

其中,欄位,屬性,方法,被統稱為類的成員。欄位,屬性 被稱為成員變數,方法被稱為成員方法

訪問標識符 <access specifier> 指定了對類及其成員的訪問規則。如果沒有指定,則使用預設的訪問標識符。類的預設訪問標識符是 internal,成員的預設訪問標識符是 private

5. 欄位與屬性

欄位一般是私有的(private),屬於類的私有信息,如:姓名,年齡,身份證號等等信息都是屬於人類的私有信息。

public class Person
{
    private string name;
    private int age;
}

 

屬性是類對外提供訪問欄位的途徑,一般是公有的(public) ,如:別人問你年齡,女孩子一般說18歲。此時她說的18歲是她自己對外主動暴露出來的,事實上她的真實年齡信息是私有的,只有她自己知道,到底是不是18歲我們其實是不清楚的。

public class Person
{
    private string name;
    private int age;
    
    public string Name
    {
        // get 訪問器
        get
        {
            return name;
        }
        // set 訪問器
        set
        {
            value=name;
        }
    }
    
    public int Age
    {
        get
        {
            return 18;
        }
        set
        {
            value = age;
        }
    }
}

Get, Set 訪問器都可以設置訪問修飾符哦,預設的訪問修飾符都是public.

c# 9.0 之後 還支持 Init訪問器, 調用方可使用屬性初始化表達式語法 , 在創建表達式中設置這些值 。 但構造完成後,這些屬性將變為只讀

 

欄位與屬性的區別

  • 欄位是私有的(private),屬性是公開的(public)。

  • 屬性具有讀寫器( get, set)

  • 欄位命名,以小駝峰命名,屬性以帕斯卡(大駝峰)命名。

  • 屬性並沒有真正存儲數據

只讀屬性

也就是只提供了, Get 訪問器,沒有Set 訪問器。

public class Person
{
    private short orderState
    
    public string OrderState
    {
        get
        {
            switch(orderState){
                case 1:
                    return "待支付";
                case 2:
                    return "待發貨";
                case 3:
                    return "待收貨";
                case 4:
                    return "已完成";
                default:
                    return "待支付";
            }
        }
    }
}

 

只寫屬性

也就是只提供了, Set 訪問器,沒有Get 訪問

public class Person
{
    private string pwd
    
    public string Password
    {
        set { value = pwd;} // 沒有Get
    }
}

 

屬性簡寫

如果一個類中,屬性只是直接對欄位進行讀寫,那麼,這個屬性欄位就可進行簡寫。

例如:

public class Person
{
    private string name;
    private int age;
    
    public string Name
    {
        get { return name; }
        set { value=name; }
    }
    
    public int Age
    {
        get { return 18; }
        set { value = age; }
    }
}
// 簡化後
public class Person
{
    public string Name {get; set;}
    public int Age {get; set;}
}

 

我們剛說過,屬性是對欄位的封裝,但是簡寫後的屬性根本就看不到類,豈不是自相矛盾嗎?其實簡寫屬性中其實隱藏了欄位,如果通過反編譯工具編譯 MS IL 或者通過反射技術去查看,我們會可以將它隱藏的欄位讀取出來。

6. 類的對象(實例)

語法:

類名 對象名 = new 類名();
如:
Person per = new Person();

  

使用對象

訪問屬性: 對象名.成員屬性
訪問行為: 對象名.方法名(…)

 

例如:

public class Person
{
    private string name
    
    public string Name
    {
        set { value = name;}
        get { return name;}
    }
    
    public void Eat()
    {
        Console.WriteLine($"姓名:{name},他正在吃飯..");
    }
}
class Program
{
    static void Main(string[] args)
    {
        Person per1 = new Person();
        per1.Name = "張三"; // 訪問屬性
        per1.Eat();  // 調用成員方法
        
        Person per2 = new Person();
        per2.Name = "李四"; // 訪問屬性
        per2.Eat();  // 調用成員方法
    }
}

輸出結果:

姓名:張三,他正在吃飯..
姓名:李四,他正在吃飯..

  

7. 構造方法

學構造方法的目的?

  • 真正知道對象具體是通過什麼得到的。

  • 能夠掌握為對象賦值的其他寫法。

構造方法的作用

  • 用於初始化一個類的對象,並返回對象的地址。

  • 簡化對象初始化的過程

語法

修飾符 類名(形參列表)
{
	...
}

public class Car 
{
    ...
    // 無參數構造器
    public Car()
    {
    	...
    }
    // 有參數構造器
    public Car(String n, String b)
    {
    	...
    } 
}

  

初始化對象的格式

類名 對象名稱 = new 構造器;
Car c = new Car();

  

構造器的分類

  • 無參數構造器(預設存在的):初始化的對象時,成員變數的數據均採用預設值。

  • 有參數構造器:在初始化對象的時候,同時可以為對象進行賦值。

註意事項

  • 任何類定義出來,預設就自帶了無參數構造器,寫不寫都有。

  • 一旦定義了有參數構造器,無參數構造器就沒有了,此時就需要自己寫一個無參數構造器了。

public class Car 
{
	...
	// 無參數構造器(預設存在的) 
}

public class Car 
{
    ...
    public Car()
    {
        // 無參數構造器(需要寫出來了)
    }    
    public Car(String n, String b)
    {
        // 有參數構造器
	} 
}

 

8. 兩個變數指向同一個對象

class Student
{
    public string Name { get; set; }
    public string Sex  { get; set; }
    public string Hobby  { get; set; }
    
    public void Study()
    {
        Console.WriteLine($"姓名:{Name},性別:{Sex},愛好:{Hobby}");
    }
}
public static void main(String[] args) 
{
    Student s1 = new Student();
    s1.Name = "小明";
    s1.Sex = '';
    s1.Hobby = "游戲、睡覺、聽課";
    s1.Study();
    // 把學生類型的s1變數賦值給學生類型的s2變數
    Student s2 = s1;
    s2.Hobby = "愛提問";
    
    Console.WriteLine(s2.Name);
    Console.WriteLine(s2.Sex);
    
    Console.WriteLine(s1.Hobby);
    s2.Study();
}

 

輸出結果:

姓名:小明,性別:男,愛好:游戲、睡覺、聽課
小明
男
愛提問
姓名:小明,性別:男,愛好:愛提問

  

記憶體分佈圖

思考:如果某個對象,被當作方法參數傳遞之後,在方法體內對象(形參)的某些屬性被修改,那麼實參對象的屬性會發生變化嗎?

9. this 關鍵字

假設有如下一段代碼:

public class Person
{
    private string name;
    private string age;
    public Person(string name,string age)
    {
        name = name; // 此處很有可能會有問題!!
        age = age;   // 此處很有可能會有問題!!
    }
}

 

編譯器很有可能分不清 name 到底是形參還是成員變數,怎麼破? this 關鍵字就可以幫忙解決。

this關鍵字

  • this關鍵字可以出現在成員方法、構造器中,代表當前對象的地址。

  • 作用:訪問當前對象的成員變數、成員方法。

public class Person
{
    private string name;
    private string age;
    public Person(string name,string age)
    {
        this.name = name; 
        this.age = age;
    }
}

10 . 作業

  1. 學生類:

    • 欄位:姓名,性別,成績,零錢

    • 屬性:姓名:性別,成績( 只寫Set訪問器),成績等級(成績<60 -->差,60<= 成績<= 70 ---> 一般,70< 成績<=80 --->中,80<成績 <=90--->良, 其他---->優, 並且此屬性只讀),零錢

    • 重載構造方法,無參,有參(姓名,性別,成績,零錢)

  2. 學生類中定義Print 方法,將 姓名,性別,成績,零錢等級 輸出到控制台。

  3. 在學生類中,定義HelpShop()方法,意思是 學生可以幫其他同學購物,然後自己獲得同學給的1元的佣金。偽代碼如下:

    public class Student
    {
        // ...欄位
        // ...屬性
        
        /// <summary>
        /// 幫其他同學購物
        /// <summary>
        /// <param name="s">被幫助的同學</param>
        /// <param name="money">購物所花費的金額</param>
        public void HelpShop(Student s, decimal money)
        {
            
        }
    }
  4. 在Main方法中創建學生類對象,通過無參構造方法創建 s1 對象,然後給 姓名,性別,成績,零錢 屬性賦值。

  5. 在Main方法中創建學生類對象,通過有參構造方法創建 s2 對象 並初始化對象。

  6. 調用s1, s2 Print方法,查看屬性值。

  7. s1 調用 HelpShop 方法, 將 s2 作為參數傳遞進去

  8. 再次調用Print 方法,查看s1, s2 的屬性值的變化。

       

視頻教程:

譽尚學教育_譽尚學教育騰訊課堂官網 (qq.com)
或者:
C# 最強入門編程(.Net 學習系列開山巨作)_嗶哩嗶哩_bilibili

 

海闊平魚躍,天高任我行,給我一片藍天,讓我自由翱翔。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如前所述,在前幾章內容中筆者簡單介紹了`記憶體讀寫`的基本實現方式,這其中包括了`CR3切換`讀寫,`MDL映射`讀寫,`記憶體拷貝`讀寫,本章將在如前所述的讀寫函數進一步封裝,並以此來實現驅動讀寫記憶體浮點數的目的。記憶體`浮點數`的讀寫依賴於`讀寫記憶體位元組`的實現,因為浮點數本質上也可以看作是一個位元組集... ...
  • # 還在愁個人博客沒有圖片放?🥱 # 前言 之前將爬取的圖片下載後,我也是放到我了我的博客上面 [ZY知識庫 · ZY - Home Page (pljzy.top)](https://pljzy.top/) 然後順便寫了一個隨機返回圖片的介面,現在我就來說一下如何使用這個介面,以便在自己的博客上 ...
  • 在 WPF 中,CanContentScroll 是 ScrollViewer 控制項的一個附加屬性,它控制滾動視圖中的內容是否按項或像素來滾動。 當 CanContentScroll 設置為 false 時,表示 ScrollViewer 控制項使用逐像素的滾動方式,這意味著滾動視圖中的內容會以像素為 ...
  • 1. 泛型 泛指某種類型。 1、使用參數形式定義 2、使用時傳入具體類型 3、編譯時檢查類型安全 4、邏輯上是多個不同類型 泛型與非泛型之間的區別 性能高:可以避免裝箱和拆箱操作 類型安全 :在進行類型轉換的時候不會拋出異常 代碼重用:定義一次,用許多種不同類型實例化 代碼擴展性好 ArrayLis ...
  • 編寫包含多個 `csproj` 的程式時,隨著項目數量的持續增加,可能涉及一些文件夾的變動,手動添加項目或者變動會變得非常麻煩,這個時候,可以利用 `dotnet cli` 幫助我們完成。 如果從零開始,我們可以新建一個解決方案。 ```powershell dotnet new sln -n to ...
  • # 依賴註入的使用 ## 構造方法註入 這是將服務註入類的最常用方法,是將依賴項註入類的首選方式,也是微軟推崇的模式。這樣,除非提供了所有構造方法註入的依賴項,否則無法構造類,顯示的聲明瞭類必需的服務,使開發人員一目瞭然。 ```csharp public class BookAppService ...
  • 假設老師類設計如下: class 老師類 { 屬性:姓名,性別,生日,工資 行為:吃飯,跑步,教學 } 學生類設計如下: class 老師類 { 屬性:姓名,性別,生日,班級 行為:吃飯,跑步,學習 } 我們秉承著,讓最簡潔的代碼,實現最最強大的功能原則,能否讓上述案例中的重覆代碼進行優化呢?我們能 ...
  • 前言 我們天天都在使用 Console.WriteLine("Hello world"); ​ Console.ReadLine(""); ​ Arrays.Sort() 為什麼Console 類 調用 方法不需要實例化而可以直接調用呢? 我們可以查看Console的源碼發現Console類定義如下 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...