第九天覆習
class Person
{
//類和對象,類中包含對象
/*
字段:存儲數據,不跟類外的打交道
屬性:保護字段,對字段的取值和設值進行限定
方法:描述對象的行爲
構造函數:初始化對象(給對象的每個屬性依次賦值)
類中的成員,如果不加訪問修飾符,默認都是private
*/
string _name;
/// <summary>
/// 屬性的本質就是兩個方法
/// </summary>
public string Name
{
get { return _name; }
set { _name = value; }
}
char _gender;
public char Gender
{
get { return _gender; }
set {
if(value != '男'&&value != '女')
{
value = '男';
}
_gender = value; }
}
int _age;
public int Age
{
get {
if (_age < 0 || _age > 100)
{
return _age = 0;
}
return _age; }
set { _age = value; }
}
//this:1.當前類的對象
public void SayHello()
{
Console.WriteLine("{0},{1},{2}", this.Name, this.Gender, this.Age);
}
//靜態方法只能訪問靜態對象,不能有實例對象,實例對象則可以都有
public static void SayHelloTwo()
{
Console.WriteLine("我是靜態方法");
}
/*
構造函數
1.沒有返回值,連void也沒有
2.構造函數名稱跟類型一模一樣
*/
public Person(string name,char gender,int age)
{
this.Name = name;
this.Gender = gender;
this.Age = age;
}
//this的第二個作用:調用當前類的構造函數
public Person(string name,char gender) : this(name,gender,0)
{
}
}
調用
static void Main(string[] args)
{
////new:1.在內存中開闢一塊空間 2.在開闢的空間創建對象 3.調用對象的構造函數
//Person zsPerson = new Person("張三",'男',18);
//zsPerson.SayHello();
//Person zsPerson = new Person("張三", '中', -18);
//zsPerson.SayHello();
//靜態對象的調用 類名.對象名
Person.SayHelloTwo();
Console.ReadKey();
}
第十天新內容
一、命名空間(namespace)
用於解決類重名問題,可以看做“類的文件夾”
如果當前項目中沒有這個類的命名空間,需要我們手動的導入這個類所在的命名空間
1.鼠標點
2.alt+shift+F10
3.記住命名空間,手動引用
在一個項目中引用另一個項目的類
1.添加引用 2.引用命名空間
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using _01第九天覆習;
namespace _02命名空間
{
class Program
{
static void Main(string[] args)
{
// List<int> list = new List<int>();
Person zsPerson = new Person("張三",'中',-18);
//zsPerson.Name = "張三";
zsPerson.SayHello();
Console.WriteLine(zsPerson.Name);
Console.ReadKey();
}
}
}
二、值類型和引用類型
區別
1.值類型和引用類型在內存上存儲的地方不一樣
2.在傳遞值類型和引用類型的時候,傳遞的方式不一樣
值類型稱之爲值傳遞,引用類型稱之爲引用傳遞
值類型:int、double、bool、char、decimal、struct、enum
引用類型:string、自定義類、數組
存儲
值類型的值存儲在內存的棧當中
引用類型的值存儲在內存的堆當中,引用類型同樣在棧上開闢一個空間,存的是堆中的地址,通過棧存的地址來和堆拉上關係
三、字符串
1.字符串的不可變性
當你給一個字符串重新賦值後,舊值並沒有被銷燬,而是重新再堆當中開闢一個空間用來存新值,這時候棧上的地址也換成了新開闢空間的地址。
當程序結束時,GC掃描整個內存,發現沒有指向的內存,GC就釋放該內存的資源。
2。我們可以將字符串看做是char類型的一個只讀數組
ToCharArray(); 將字符串轉換爲char數組
new string(char[] chs):將char數組轉換爲string
static void Main(string[] args)
{
//可以將string類型看做是char類型的只讀數組
string s = "abcdefg";
// s[0] = b; 不能這樣做,因爲是隻讀的
//首先將字符串轉換爲char類型的數組
char[] chs = s.ToCharArray();
chs[0] = 'b';
//將字符數組轉回字符串
s = new string(chs);
Console.WriteLine(s);
//既然可以將string看做char烈性的只讀數組,所以可以通過索引去訪問字符串中的某一個元素
Console.WriteLine(s[1]);
Console.ReadKey();
}
關鍵字:StringBuilder() 不重新開闢空間
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
string str = null;
//創建一個計時器,用來記錄程序運行的時間
Stopwatch sw = new Stopwatch();
sw.Start();//開始計時
for (int i = 0; i < 1000; i++)
{
//00:00:00.0017008
//str += i;
//00:00:00.0002480
sb.Append(i);
}
sw.Stop();//結束計時
Console.WriteLine(sb.ToString());
Console.WriteLine(sw.Elapsed);
Console.ReadKey();
}
字符串提供的各種方法
Length:獲得字符串的長度
ToUpper() :將字符串轉換爲大寫
ToLower():將字符串轉換爲小寫
Equals(Equals(Two,StringComparison.OrdinalIgnoreCase)):比較字符串,忽略大小寫
static void Main(string[] args)
{
////練習1:隨機輸入一個名字,然後輸出他的字符串長度 Length:可以得到字符串的長度
//Console.WriteLine("輸入名字");
//string name = Console.ReadLine();
//Console.WriteLine("{0}的長度是{1}", name, name.Length);
//Console.ReadKey();
////練習2:兩個學員輸入各自最喜歡的課程名稱,判斷是否一致,如果相等,則輸出你們兩喜歡相同的課程,
//// 如果不相同,則輸出你們兩喜歡不相同的課程
//Console.WriteLine("請輸入你喜歡的課程");
//string One = Console.ReadLine();
//Console.WriteLine("請輸入你喜歡的課程");
//string Two = Console.ReadLine();
//if (One == Two)
//{
// Console.WriteLine("你們喜歡的課程相同");
//}
//else
//{
// Console.WriteLine("你們喜歡的課程不相同");
//}
//Console.ReadKey();
//練習3:上題中兩位同學輸入C#和c#代表同一門課,怎麼辦
Console.WriteLine("請輸入你喜歡的課程");
string One = Console.ReadLine();
// One = One.ToUpper();//將字符串轉換爲大寫
// One = One.ToLower();//將字符串轉換爲小寫
Console.WriteLine("請輸入你喜歡的課程");
string Two = Console.ReadLine();
// Two = Two.ToUpper();//將字符串轉換爲大寫
// Two = Two.ToLower();//將字符串轉換爲小寫
if (One.Equals(Two,StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("你們喜歡的課程相同");
}
else
{
Console.WriteLine("你們喜歡的課程不相同");
}
Console.ReadKey();
}
5.Split():分割字符串,返回字符串類型的數組
////字符串的分割Split
//string s = "a b c sdf _ + = , asd";
//char[] chs = { ' ', '_', '+', '=' };
//string[] str = s.Split(chs,StringSplitOptions.RemoveEmptyEntries);
//Console.ReadKey();
/*
練習:從日期字符串{"2020-08-08"}中分析出年,月,日;2020年08月08日
讓用戶輸入一個日期格式如:2020-01-02,你輸入你輸入的日期爲2020年1月2日
*/
string time = "2020-08-08";
char[] chs = { '-' };
string[] date = time.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine("{0}年{1}月{2}日", date[0], date[1], date[2]);
Console.ReadKey();
6.Replace() :替換字符
string str = "關鍵人物楊老";
if (str.Contains("楊老"))
{
//將楊老替換爲**
str = str.Replace("楊老", "**");
}
Console.WriteLine(str);
Console.ReadKey();
7.Substring():截取字符串
//字符串截取
string str = "今天天空晴朗,處處好風光";
//只截取前面兩個字符
//str = str.Substring(0,1);
//截掉第一個字符
str = str.Substring(1);
Console.WriteLine(str);
Console.ReadKey();
8.StartsWith()和EndsWith():以什麼開頭和以什麼結尾,返回值都是bool類型
string str = "今天天空晴朗,處處好風光";
if (str.StartsWith("天天"))
{
Console.WriteLine("是的");
}
else
{
Console.WriteLine("不是的");
}
Console.ReadKey();
9.IndexOf和LastIndexOf:查找字符所在字符串中的位置。返回值都是Int類型
//string str = "今天天空晴朗,處處天天好風光";
////從什麼位置開始找
//int index = str.IndexOf('天',2);
//Console.WriteLine(index);
//Console.ReadKey();
//string str = "今天天空晴朗,處處天天好風光";
//int index = str.LastIndexOf('天');
//Console.WriteLine(index);
//Console.ReadKey();
//LastIndexOf Substring 配合使用截取字符串
string path = @"C:\a\b\c\d\e\f\g\\hh\蒼老師蒼.wav";
int index = path.LastIndexOf("\\");
path = path.Substring(index+1);
Console.WriteLine(path);
Console.ReadKey();
10.Trim():去掉字符串中的空格
string str = " hahaha ";
str = str.Trim();//去掉字符串中所有的空格
str = str.TrimStart();//只去掉前面的空格
str = str.TrimEnd();//只去掉後面的空格
Console.Write(str);
Console.ReadKey();
11.IsNullOrEmpty():判斷字符串是否爲空
string str = null;
if (string.IsNullOrEmpty(str))
{
Console.WriteLine("是的");
}
else
{
Console.WriteLine("不是的");
}
12.Join():將數組按照指定的字符串連接,返回一個字符串
string[] names = { "張三", "李四", "王五", "趙六" };
//string str = string.Join("|", names);
string str = string.Join("|", "張三", "李四", "王五", "趙六");
Console.WriteLine(str);
Console.ReadKey();
字符串的練習(這個一定要練熟)
static void Main(string[] args)
{
////練習1.接收用戶輸入的字符串,將其中的字符以與輸入相反的順序輸出
//Console.WriteLine("請輸入一個字符串");
//string str = Console.ReadLine();
//char[] chs = str.ToCharArray();
//char temp = 'a';
//for (int i = 0; i < chs.Length/2; i++)
//{
// temp = chs[i];
// chs[i] = chs[chs.Length - 1 - i];
// chs[chs.Length - 1 - i] = temp;
//}
//str = new string(chs);
//Console.WriteLine(str);
//Console.ReadKey();
////練習2.接收用戶輸入的依據英文,將其中的單詞以反序輸出。
//Console.WriteLine("請輸入一個字符串");
//string strOne = Console.ReadLine();
//string[] strNew = strOne.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
//for (int i = 0; i < strNew.Length/2; i++)
//{
// string temp = strNew[i];
// strNew[i] = strNew[strNew.Length - 1 - i];
// strNew[strNew.Length - 1 - i] = temp;
//}
////for (int i = 0; i < strNew.Length; i++)
////{
//// Console.Write("{0} ",strNew[i]);
////}
//strOne = string.Join(" ", strNew);
//Console.WriteLine(strOne);
//Console.ReadKey();
////練習3.從Eemail中提取用戶名和域名:[email protected]
//string email = "[email protected]";
//int index = email.IndexOf('@');
//string name = email.Substring(0, index);
//string yuMing = email.Substring(index+1);
//Console.WriteLine("用戶名:{0},域名:{1}", name, yuMing);
//Console.ReadKey();
/*
文本文件中存儲多個文章標題、作者、標題和作者之間用若干空格(數量不定)
隔開,每行一個,標題有長有短,輸出到控制檯的時候最多標題長度10,如果
超過10,則截取長度8的子串並且最後添加"....",加一個豎線後輸出作者的名字
*/
////1.拿到文本文件裏面的數據
//string path = @"C:\Users\Administrator\Desktop\1.txt";
//string[] contents = File.ReadAllLines(path, Encoding.Default);
//for (int i = 0; i < contents.Length; i++)
//{
// string[] ss = contents[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// Console.WriteLine((ss[0].Length>10?ss[0].Substring(0,8)+"......":ss[0]) + "|" + ss[1]);
//}
//Console.ReadKey();
////練習4.讓用戶輸入一句話,找出所有e的位置
//Console.WriteLine("請輸入一句話");
//string strTwo = Console.ReadLine();
//int index = strTwo.IndexOf('e');
//Console.WriteLine("第一次出現e的位置是{0}", index);
////循環體:從上一次出現e的位置加1的位置找下一次e出現的位置
////循環條件:index != -1
//int count = 1;
//while (index != -1)
//{
// count++;
// index = strTwo.IndexOf("e", index + 1);
// if (index == -1)
// {
// break;
// }
// Console.WriteLine("第{0}此出現e的位置是{1}", count, index);
//}
//Console.ReadKey();
////練習5.讓用戶輸入一句話,判斷這句話有沒有邪惡,如有鞋子就替換成**
//Console.WriteLine("請輸入一句話");
//string strThere = Console.ReadLine();
//if (strThere.Contains("邪惡"))
//{
// strThere = strThere.Replace("邪惡", "****");
//}
//Console.WriteLine(strThere);
//Console.ReadKey();
////練習6.把{"諸葛亮","卡卡西","鳥叔","卡哇伊"}變成諸葛亮|卡卡西|鳥叔|卡哇伊,然後再把|切割掉
//string[] strs = { "諸葛亮", "卡卡西", "鳥叔", "卡哇伊" };
//string strFor = string.Join("|", strs);
//char[] chs = { '|' };
//strs = strFor.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
//for (int i = 0; i < strs.Length; i++)
//{
// Console.WriteLine(strs[i]);
//}
//Console.WriteLine(strFor);
//Console.ReadKey();
}
四、面向對象(繼承)
把多個類中重複的成員單獨拿出來封裝成一個類,作爲這幾個類的父類,從而解決多個類中出現重複的成員造成代碼冗餘
Student、teacher、driver 子類 派生類
Person 父類 基類
子類繼承父類的:屬性、方法。不能繼承父類的私有字段
繼承的特性
1、繼承的單根性(子類只能繼承一個父類)
2、繼承的傳遞性(父類讓一個子類繼承後,其他子類在繼承這個子類時,一樣可以訪問到父類。多個子類傳遞繼承,則都可以訪問到所傳遞繼承的類)
子類不會繼承父類的構造函數,但是,子類會默認的調用父類無參數的構造函數。讓子類可以使用父類中的成員。
所以,如果在父類中重新寫了一個有參數的構造函數之後,那個無參數的就被幹掉了,子類就調用不到,所以子類會報錯。
解決辦法
1.在父類中在寫一個無參數的構造函數(一般不這麼做)
2.使用關鍵字:base調用父類中的構造函數
object是所有類的基類。
關鍵字:new隱藏父類成員
子類有成員跟父類成員重名,父類的會被默認隱藏
繼承相關代碼
父類
class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private char _gender;
public char Gender
{
get { return _gender; }
set { _gender = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public Person(string name,int age,char gender)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
}
public void SayHello()
{
Console.WriteLine("我是父類的SayHello");
}
}
司機類
class Driver:Person
{
public Driver(string name,int age,char gender,int driverTime):base(name,age,gender)
{
this.DriverTime = driverTime;
}
private int _driverTime;
public int DriverTime
{
get { return _driverTime; }
set { _driverTime = value; }
}
public void DriverSay()
{
Console.WriteLine("我是一名{0},我有{1}歲,我是{2}人,我的駕齡是{3}", this.Name, this.Age, this.Gender, this.DriverTime);
}
public new void SayHello()
{
Console.WriteLine("我是司機類的SayHello");
}
}
記者類
class Reporter:Person
{
public Reporter(string name,int age,char gender,string hobby):base(name,age,gender)
{
this.Hobby = hobby;
}
private string _hobby;
public string Hobby
{
get { return _hobby; }
set { _hobby = value; }
}
public void ReporterSay()
{
Console.WriteLine("我是一名{0},我有{1}歲,我是{2}人,我的愛好是{3}",this.Name,this.Age,this.Gender,this.Hobby);
}
//使用new關鍵字將從父類中繼承的重名方法隱藏
public new void SayHello()
{
Console.WriteLine("我是記者類的SayHello");
}
}
程序員類
class Programmer:Person
{
public Programmer(string name,int age,char gender,int time):base(name,age,gender)
{
this.Time = time;
}
private int _time;
public int Time
{
get { return _time; }
set { _time = value; }
}
public void ProgrammerSay()
{
Console.WriteLine("我是一名{0},我有{1}歲,我是{2}人,我的工齡是{3}", this.Name, this.Age, this.Gender, this.Time);
}
public new void SayHello()
{
Console.WriteLine("我是程序員的SayHello");
}
}
在MAIN函數中調用
static void Main(string[] args)
{
//記者:我是一個狗仔,我愛好是偷拍,我的年齡是34,我是一個男狗仔
//司機:我叫舒馬赫 我的年齡是43 我是男人 我的駕齡是23年
//程序員:我叫孫權 我的年齡是23 我是男生 我的工作年限是3年
Reporter reporter = new Reporter("記者",34,'男',"偷拍");
reporter.ReporterSay();
Driver driver = new Driver("司機", 43, '男', 20);
driver.DriverSay();
Programmer programmer = new Programmer("程序員", 25, '男', 3);
programmer.ProgrammerSay();
programmer.SayHello();
Console.ReadKey();
}