C#教程8:面向对象编程【01】
一、OOP面向?qū)ο蠖x
面向?qū)ο缶幊?(OOP) 是一種編程范式,它使用對象及其交互來設(shè)計(jì)應(yīng)用程序和計(jì)算機(jī)程序。
OOP中有一些基本的編程概念:
- Abstraction 抽象
- Polymorphism? 多態(tài)
- Encapsulation? ?封裝
- Inheritance? ?繼承
????????抽象是通過建模適合問題的類來簡化復(fù)雜的現(xiàn)實(shí)。多態(tài)性是對不同的數(shù)據(jù)輸入以不同的方式使用運(yùn)算符或函數(shù)的過程。封裝對其他對象隱藏了一個類的實(shí)現(xiàn)細(xì)節(jié)。繼承是一種使用已經(jīng)定義的類形成新類的方法。
二、C# 對象
????????對象是 C# OOP 程序的基本構(gòu)建塊。對象是數(shù)據(jù)和方法的組合。數(shù)據(jù)和方法稱為對象的成員。在 OOP 程序中,我們創(chuàng)建對象。這些對象通過方法相互通信。每個對象都可以接收消息、發(fā)送消息和處理數(shù)據(jù)。
????????創(chuàng)建對象有兩個步驟。首先,我們定義一個類。類是對象的模板。它是描述類的對象都共享的狀態(tài)和行為的藍(lán)圖。一個類可用于創(chuàng)建許多對象。在運(yùn)行時從一個類創(chuàng)建的對象稱為該特定類的實(shí)例。
Program.cs
var b = new Being(); Console.WriteLine(b);class Being {}在我們的第一個示例中,我們創(chuàng)建了一個簡單的對象。
class Being {}這是一個簡單的類定義。模板的主體是空的。它沒有任何數(shù)據(jù)或方法。
var b = new Being();我們創(chuàng)建了一個存在類的新實(shí)例。為此,我們有新的關(guān)鍵字。 b 變量是創(chuàng)建對象的句柄。
Console.WriteLine(b);????????我們將對象打印到控制臺以獲取對象的一些基本描述。打印一個對象是什么意思?當(dāng)我們打印一個對象時,我們實(shí)際上調(diào)用了它的 ToString 方法。但是我們還沒有定義任何方法。這是因?yàn)閯?chuàng)建的每個對象都繼承自基礎(chǔ)對象。它具有一些在所有創(chuàng)建的對象之間共享的基本功能。其中之一是 ToString 方法。
$ dotnet run Being三 C# 對象的屬性
????????對象屬性是捆綁在類實(shí)例中的數(shù)據(jù)。對象屬性稱為實(shí)例變量或成員字段。實(shí)例變量是在類中定義的變量,類中的每個對象都有一個單獨(dú)的副本。
Program.cs
var p1 = new Person(); p1.name = "Jane";var p2 = new Person(); p2.name = "Beky";Console.WriteLine(p1.name); Console.WriteLine(p2.name);class Person {public string name; }在上面的 C# 代碼中,我們有一個帶有一個成員字段的 Person 類。
class Person {public string name; }我們聲明一個名稱成員字段。 public 關(guān)鍵字指定成員字段可以在類塊之外訪問。
var p1 = new Person(); p1.name = "Jane";我們創(chuàng)建一個 Person 類的實(shí)例,并將 name 變量設(shè)置為“Jane”。我們使用點(diǎn)運(yùn)算符來訪問對象的屬性。
var p2 = new Person(); p2.name = "Beky";我們創(chuàng)建 Person 類的另一個實(shí)例。在這里,我們將變量設(shè)置為“Beky”。
Console.WriteLine(p1.name); Console.WriteLine(p2.name);我們將變量的內(nèi)容打印到控制臺。
$ dotnet run Jane BekyPerson 類的每個實(shí)例都有一個單獨(dú)的名稱成員字段副本。
四、C# 的方法
????????方法是定義在類體內(nèi)的函數(shù)。它們用于使用我們對象的屬性執(zhí)行操作。方法為我們的程序帶來了模塊化。
????????方法在 OOP 范式的封裝概念中是必不可少的。例如,我們的 AccessDatabase 類中可能有一個 Connect 方法。我們不需要知道 Connect 方法是如何連接到數(shù)據(jù)庫的。我們只需要知道它是用來連接數(shù)據(jù)庫的。這對于劃分編程職責(zé)至關(guān)重要,尤其是在大型應(yīng)用程序中。
????????對象分組狀態(tài)和行為,方法代表對象的行為部分。
Program.cs
var c = new Circle(); c.SetRadius(5);Console.WriteLine(c.Area());class Circle {private int radius;public void SetRadius(int radius){this.radius = radius;}public double Area(){return this.radius * this.radius * Math.PI;} }????????在代碼示例中,我們有一個 Circle 類。我們定義了兩種方法。
private int radius;????????我們有一個成員字段。它是圓的半徑。私有關(guān)鍵字是訪問說明符。它告訴變量僅限于外部世界。如果我們想從外部修改這個變量,我們必須使用公開可用的 SetRadius 方法。這樣我們就可以保護(hù)我們的數(shù)據(jù)。
public void SetRadius(int radius) {this.radius = radius; }????????這是 SetRadius 方法。 this 變量是一個特殊變量,我們使用它來訪問方法中的成員字段。 this.radius 是一個實(shí)例變量,而 radius 是一個局部變量,僅在 SetRadius 方法內(nèi)有效。
var c = new Circle(); c.SetRadius(5);????????我們創(chuàng)建一個 Circle 類的實(shí)例,并通過在圓的對象上調(diào)用 SetRadius 方法來設(shè)置它的半徑。我們使用點(diǎn)運(yùn)算符來調(diào)用該方法。
public double Area() {return this.radius * this.radius * Math.PI; }Area 方法返回圓的面積。 Math.PI 是一個內(nèi)置常量。
$ dotnet run 78.5398163397448五、C#?訪問修飾符
????????訪問修飾符設(shè)置方法和成員字段的可見性。 C# 有四個基本的訪問修飾符:public、protected、private 和 internal。可以從任何地方訪問公共成員。受保護(hù)的成員只能在類本身以及繼承的類和父類中訪問。私有成員僅限于包含類型,例如僅在其類或接口內(nèi)。可以從同一個程序集(exe 或 DLL)中訪問內(nèi)部成員。
????????還有兩種修飾符組合:protected internal 和 private protected。受保護(hù)的內(nèi)部類型或成員可以被聲明它的程序集中的任何代碼訪問,也可以從另一個程序集中的派生類中訪問。私有受保護(hù)類型或成員只能在其聲明程序集中、通過同一類中的代碼或從該類派生的類型中訪問。
????????訪問修飾符保護(hù)數(shù)據(jù)免受意外修改。它們使程序更加健壯。
| public | + | + | + | + | + |
| protected | + | o | + | + | o |
| internal | + | + | o | o | o |
| private | + | o | o | o | o |
| protected internal | + | + | + | + | o |
| private protected | + | o | o | + | o |
上表總結(jié)了 C# 訪問修飾符(+ 可訪問,o 不可訪問)。
Program.cs
var p = new Person(); p.name = "Jane";p.SetAge(17);Console.WriteLine($"{p.name} is {p.GetAge()} years old");class Person {public string name;private int age;public int GetAge(){return this.age;}public void SetAge(int age){this.age = age;} }在上面的程序中,我們有兩個成員字段。一個是公開的,另一個是私有的。
public int GetAge() {return this.age; }????????如果成員字段是私有的,則訪問它的唯一方法是通過方法。如果我們想修改類之外的屬性,則必須將方法聲明為 public。這是數(shù)據(jù)保護(hù)的一個重要方面。
public void SetAge(int age) {this.age = age; }SetAge 方法使我們能夠從類定義之外更改私有年齡變量。
var p = new Person(); p.name = "Jane";????????我們創(chuàng)建一個 Person 類的新實(shí)例。因?yàn)?name 屬性是公開的,所以我們可以直接訪問它。但是,不建議這樣做。
p.SetAge(17);SetAge 方法修改年齡成員字段。無法直接訪問或修改它,因?yàn)樗宦暶鳛樗接小?/p> Console.WriteLine($"{p.name} is {p.GetAge()} years old");
最后,我們訪問這兩個成員來構(gòu)建一個字符串。
$ dotnet run Jane is 17 years old具有私有訪問修飾符的成員字段不會被派生類繼承。
Program.cs
var derived = new Derived(); derived.info();class Base {public string name = "Base";protected int id = 5323;private bool isDefined = true; }class Derived : Base {public void info(){Console.WriteLine("This is Derived class");Console.WriteLine("Members inherited");Console.WriteLine(this.name);Console.WriteLine(this.id);// Console.WriteLine(this.isDefined);} }????????在前面的程序中,我們有一個繼承自基類的派生類。基類具有三個成員字段。所有這些都具有不同的訪問修飾符。 isDefined 成員不被繼承。私有修飾符可以防止這種情況。
class Derived : Base????????派生類繼承自基類。要從另一個類繼承,我們使用冒號 (:) 運(yùn)算符。
Console.WriteLine(this.name); Console.WriteLine(this.id); // Console.WriteLine(this.isDefined);????????公共和受保護(hù)的成員由派生類繼承。它們可以被訪問。私有成員不會被繼承。訪問成員字段的行被注釋掉。如果我們?nèi)∠⑨屧撔?#xff0c;代碼將無法編譯。
$ dotnet run ... warning CS0414: The field 'Base.isDefined' is assigned but its value is never used ... This is Derived class Members inherited Base 5323六、C# 構(gòu)造函數(shù)
????????構(gòu)造函數(shù)是一種特殊的方法。創(chuàng)建對象時會自動調(diào)用它。構(gòu)造函數(shù)不返回值。構(gòu)造函數(shù)的目的是初始化一個對象的狀態(tài)。構(gòu)造函數(shù)與類同名。構(gòu)造函數(shù)是方法,所以它們也可以被重載。
????????構(gòu)造函數(shù)不能被繼承。它們按繼承順序調(diào)用。如果我們不為類編寫任何構(gòu)造函數(shù),C# 提供了一個隱式默認(rèn)構(gòu)造函數(shù)。如果我們提供任何類型的構(gòu)造函數(shù),則不提供默認(rèn)值。
Program.cs
new Being(); new Being("Tom");class Being {public Being(){Console.WriteLine("Being is created");}public Being(string being){Console.WriteLine($"Being {being} is created");} }我們有一個存在類。這個類有兩個構(gòu)造函數(shù)。第一個不帶參數(shù);第二個接受一個參數(shù)。
public Being(string being) {Console.WriteLine($"Being {being} is created"); }此構(gòu)造函數(shù)采用一個字符串參數(shù)。
new Being();創(chuàng)建了一個存在類的實(shí)例。這次在對象創(chuàng)建時調(diào)用不帶參數(shù)的構(gòu)造函數(shù)。
$ dotnet run Being is created Being Tom is created在下一個示例中,我們啟動類的數(shù)據(jù)成員。變量的初始化是構(gòu)造函數(shù)的典型工作。
Program.cs
var name = "Lenka"; var born = new DateTime(1990, 3, 5);var friend = new MyFriend(name, born); friend.Info();class MyFriend {private DateTime born;private string name;public MyFriend(string name, DateTime born){this.name = name;this.born = born;}public void Info(){Console.WriteLine("{0} was born on {1}",this.name, this.born.ToShortDateString());} }我們有一個帶有數(shù)據(jù)成員和方法的 MyFriend 類。
private DateTime born; private string name;我們在類定義中有兩個私有變量。
public MyFriend(string name, DateTime born) {this.name = name;this.born = born; }在構(gòu)造函數(shù)中,我們初始化了兩個數(shù)據(jù)成員。 this 變量是用于引用對象變量的處理程序。
var friend = new MyFriend(name, born); friend.Info();我們創(chuàng)建一個帶有兩個參數(shù)的 MyFriend 對象。然后我們調(diào)用對象的 Info 方法。
$ dotnet run Lenka was born on 3/5/1990七、C# 構(gòu)造鏈
????????構(gòu)造函數(shù)鏈接是類從構(gòu)造函數(shù)調(diào)用另一個構(gòu)造函數(shù)的能力。要從同一類調(diào)用另一個構(gòu)造函數(shù),我們使用 this 關(guān)鍵字。
Program.cs
new Circle(5); new Circle();class Circle {public Circle(int radius){Console.WriteLine($"Circle, r={radius} is created");}public Circle() : this(1) { } }我們有一個 Circle 課程。該類有兩個構(gòu)造函數(shù)。一個帶一個參數(shù),一個不帶任何參數(shù)。
public Circle(int radius) {Console.WriteLine("Circle, r={0} is created", radius); }這個構(gòu)造函數(shù)接受一個參數(shù)——半徑。
public Circle() : this(1) { }這是沒有參數(shù)的構(gòu)造函數(shù)。它只是調(diào)用另一個構(gòu)造函數(shù)并給它一個默認(rèn)的半徑 1。
$ dotnet run Circle, r=5 is created Circle, r=1 is created八、C# ToString 方法
????????每個對象都有一個 ToString 方法。它返回對象的人類可讀表示。默認(rèn)實(shí)現(xiàn)返回對象類型的完全限定名稱。請注意,當(dāng)我們使用對象作為參數(shù)調(diào)用 Console.WriteLine 方法時,會調(diào)用 ToString。
Program.cs
var b = new Being(); var o = new Object();Console.WriteLine(o.ToString()); Console.WriteLine(b.ToString()); Console.WriteLine(b);class Being {public override string ToString(){return "This is Being class";} }????????我們有一個存在類,我們在其中覆蓋了 ToString 方法的默認(rèn)實(shí)現(xiàn)。
public override string ToString() {return "This is Being class"; }????????創(chuàng)建的每個類都繼承自基礎(chǔ)對象。 ToString 方法屬于該對象類。我們使用覆蓋關(guān)鍵字來通知我們正在覆蓋一個方法。
var b = new Being(); var o = new Object();????????我們創(chuàng)建一個自定義對象和一個內(nèi)置對象。
Console.WriteLine(o.ToString()); Console.WriteLine(b.ToString());????????我們在這兩個對象上調(diào)用 ToString 方法。
Console.WriteLine(b);????????正如我們之前指定的,將對象作為參數(shù)放置到 Console.WriteLine 將調(diào)用其 ToString 方法。這一次,我們隱式調(diào)用了該方法。
$ dotnet run System.Object This is Being class This is Being class九、C#對象初始化
????????對象初始化器讓我們在創(chuàng)建時為對象的任何可訪問字段或?qū)傩苑峙渲?#xff0c;而無需調(diào)用構(gòu)造函數(shù)。屬性或字段在 {} 括號內(nèi)分配。此外,我們可以為構(gòu)造函數(shù)指定參數(shù)或省略參數(shù)。
Program.cs
var u = new User { Name = "John Doe", Occupation = "gardener" }; Console.WriteLine(u);class User {public User() {}public string Name { set; get; }public string Occupation { set; get; }public override string ToString(){return $"{Name} is a {Occupation}";} }在示例中,我們使用對象初始化器語法創(chuàng)建一個新用戶。
public User() {}我們定義了一個空的構(gòu)造函數(shù)。
public string Name { set; get; } public string Occupation { set; get; }我們有兩個屬性:姓名和職業(yè)。
var u = new User { Name = "John Doe", Occupation = "gardener" };我們將值分配給 {} 括號中的屬性。
$ dotnet run John Doe is a gardener總結(jié)
以上是生活随笔為你收集整理的C#教程8:面向对象编程【01】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#教程7:数组
- 下一篇: c# char unsigned_dll