面向對象
對象:
我們把這些具有相同屬性和相同的方法的對象進一步的封裝,抽象出來類這個概念,類就是模子,確定了對象應該具有的屬性和方法。
對象是根據類創建出來的。
類:
語法:
【public】class 類名
{
字段;//Field
屬性;//Property
方法;//Method
}
寫好一個類,我們需要創建這個類的對象。
那麼我們管創建這個類的對象過程稱之為類的實例化。
使用關鍵字 new;
Person zhangsan = new Person();
this:
表示當前這個類的對象。有時候不加會出錯。
Console.WriteLine("你好我叫{0},我今年{1}歲,我是{2}",this._name,this._age,this._gender);
類是不占內存的,而對象是占內存的。
類的實例化時也就是對象有初值,字段有初值所以就占內存了。
屬性
屬性的作用就是保護字段,對字段的賦值和取值進行限定。
屬性的本質就是兩個方法【1.get 2. set】
get,set都有我們稱之為可讀可寫屬性;
只有get我們稱之為只讀屬性;
只有set我們稱之為只寫屬性;
//字段
public string _name;
//屬性
public string Name {
//當你需要輸出的時候就調用get方法
get { return _name; }
//當你給屬性賦值的時候會調用set方法
set { _name = value; }
}
做一個不恰當的例子:字段是女人,屬性是男人,要訪問字段就必須通過屬性。
當然了後期為了保證字段的安全性就需要將字段換成私有的,其他的類就不能直接訪問,就需要屬性裡的get,set方法。當然還可以對字段的輸入進行一些限定。
private int _age;
public int AGE {
get { return _age; }
set {
if (value < 0 || value > 100)
{
value = 0;
}
_age = value;
}
}
main方法調用
Person zhangsan = new Person();
zhangsan.AGE = -12;
//輸出就是0,因為if判斷了
對性別進行限定:
private char _gender;
public char Gender {
get {
if (_gender !='男' && _gender !='女')
{
return _gender = '男';
}
return _gender; }
set { _gender = value; }
}
main方法調用:
//創建Person類的對象
Person zhangsan = new Person();
zhangsan.Gender = '你';
//輸出是男
總結:靜態成員必須使用類名去調用,而實例成員使用對象名調用。
靜態函數只能訪問靜態成員,不允許訪問實例成員
非靜態函數都可以訪問。
靜態類中只允許有靜態成員,不允許出現實例成員
使用:
1.如果你想要你的類當做一個工具類來使用,這個時候可以考慮將類寫成靜態類。
2.靜態類在整個項目裡資源共享。
3.只有在程序結束后才會釋放資源。
堆 棧 靜態存儲區域
靜態的東西都放在靜態存儲區域,越多的話越卡;
釋放資源:GC—Garbage Collection垃圾回收器
構造函數
作用:幫助我們初始化對象(給對象的每個屬性依次賦值)
構造函數是一個特殊的方法:
1.構造函數沒有返回值,連void也不能寫
2.構造函數的名稱必須和類名一致
構造方法可以有重載
創建對象的時候會執行構造函數
類當中會有一個默認的無參的構造函數,當你寫了一個后,不管你寫的是有參的還是無參的,那個默認的都被幹掉了;
new關鍵字
Student sd = new Student("張三",12,'男',45);
new幫我們做了三件事:
1.在內存中開闢了一塊空間
2.在開闢的空間裡創建對象
3.調用對象的構造函數進行初始化對象
this關鍵字
1.代表當前類的對象
2.在類當中顯示的調用本類的構造函數 語法 — :this
我覺得是重載,this上邊有參數調用多的,下邊調用少的可以用this調用上邊全的,可以避免代碼冗餘
public Student(string name, int age, char gender, int english)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
this.English = english;
}
public Student(string name,int age):this(name,age,' ',45) {
}
調用
Student dsd = new Student("李四",45,'女',78);
dsd.SayHell();
dsd.SayScore();
Console.ReadKey();
Student hh = new Student("王五",78);
hh.SayHell();
hh.SayScore();
Console.ReadKey();
析構函數
當程序結束的時候 析構函數才執行
幫助我們釋放資源,不過GC可以自動進行垃圾回收如果想盡快釋放就用析構函數
~Student() {
Console.WriteLine("我是析構函數");
}
命名空間
可以認為類是屬於命名空間的
如果當前項目沒有這個類的命名空間,需要我們手動的導入類的所在就是引入命名空間。
手動添加,提示添加
在一個項目添加另一個項目的類
1.添加引用
2.引用命名空間
using _01複習//這樣就可以使用了
值類型和引用類型
區別:
1.值類型和引用類型在內存存儲的地方不一樣
2.在傳遞值類型和傳遞引用類型的時候,傳遞的方式不一樣
值類型我們稱之為值傳遞,引用類型我們稱之為引用傳遞
值類型:int,double,bool,char,decimal,struct,enum,
引用類型:string,自定義類,數組
存儲:
值類型的值存儲在內存的棧中。
引用類型的值存儲在內存的堆中。
字符串
字符串的不可變性;
一般的如int等重新賦值的就把原來的值幹掉,但是字符串從新賦值原來的值並沒有被銷毀,而是從新在堆內開闢新的空間存儲新的值。
這樣會產生垃圾,等待程序結束后GC掃描沒有指向的值才會清理垃圾。
可以將string類型,看做是char類型的一個只讀數組;
修改string裡邊的一個字符
ToCharArray();將字符串轉化char數組;
new string(char[] chs);能夠將char數組轉化為字符串。
測試string開空間測試
string str = null;//00:00:00.9660700
StringBuilder sb = new StringBuilder();//00:00:00.0168688
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100000; i++)
{
//str += 1;
sb.Append(i);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
Console.ReadKey();
str花費了大量的時間開空間,所以for循環用了00:00:00.9660700
StringBuilder();只用了00:00:00.0168688
字符串的各種方法
Length:得到字符串的長度
string name = "sadfsadf";
Console.WriteLine(name.Length);
ToUpper():將字符轉換成大寫。
ToLower():將字符轉換成小寫。
string name = "sadfasf";
name = name.ToUpper();
Console.WriteLine(name);//SADFASF
Equals():比較字符是否一樣(name.Equals(age,StringComparison.OrdinalIgnoreCase))參數是忽略大小寫
string name = "sadfasfKJHH";
string age = "sadfasfKJhh";
if (name.Equals(age,StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("兩個字符一樣");
}
Split():切割,chs裡邊的東西不要,StringSplitOptions.RemoveEmptyEntries:不要空格
string name ="sadfa s f K J _ = + ,HH";
char[] chs = {' ', '_', '=', '+' };
string[] str = name.Split(chs,StringSplitOptions.RemoveEmptyEntries);
提取日期
string date = "2021-12-1";
char[] chs ={'-'};
string[] day = date.Split(chs,StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine("{0}年{1}月{2}日",day[0],day[1],day[2]);
替換關鍵字
Contains(“老趙”);判斷是否出現
.Replace(“老趙”, “***”):將之替換
string str = "關鍵字老趙";
if (str.Contains("老趙"))
{
str = str.Replace("老趙", "***");
}
Console.WriteLine(str);
.Substring(起始位置); -->从起始位置到末尾
string str = "關鍵字老趙";
str=str.Substring(1);
Console.WriteLine(str);//鍵字老趙
.Substring(起始位置,长度);
string str = "關鍵字老趙";
str=str.Substring(1,2);
Console.WriteLine(str);//鍵字
.StartsWith(“關”)):是不是以關開頭。
.EndsWith(“趙”):是不是以趙結尾
string str ="關鍵字老趙";
if (str.EndsWith("趙"))
{
Console.WriteLine("是的");
}
else
{
Console.WriteLine("不是");
}
str.IndexOf(‘關’);得到關字出現的位置,索引數字
int index = str.IndexOf(‘關’,2);這個是找第二次出現的位置
str.LastIndexOf(‘老’);最後一次出現
string str = "關鍵字老趙";
int index = str.IndexOf('關');
Console.WriteLine(index);
str=str.Trim();去掉前后的空格
str.TrimStart();去掉前边的空格
str.TrimEnd();去掉后边的空格
string str = String.Join("|", names);
String.Join(‘进行连接的字符’,字符串数组);//拼接字符