---
# System prepended metadata

title: '**C#實作課程-Lesson 4**'
tags: [C#]

---

###### tags: `C#`
# **C#實作課程-Lesson 4**
#    列舉 enum
#    類別的繼承
## 基底類別(父類別) vs 衍生類別(子類別)
語法： 衍生類別:基底類別
●衍生類別只能繼承1個基底類別
●如果程式碼不複雜，可將基底類別與其衍生類別寫在同一個檔案(.cs)

```csharp=
public enum LogTypeDef
    {
        SystemError,Error,Information
    }
    public class Log
    {
        public LogTypeDef LogType { get; set; }
        public string LogContent { get; set; }
        public DateTime LogTime { get; set; }
        public string MailAddr { get; set; }
        public void WriteLog()
        {
            if (this.LogType ==LogTypeDef.SystemError)
            Console.WriteLine($"send email to{MailAddr}");
            Console.WriteLine(LogContent);
        }
    }
    public class dbLog:Log
    {
        public void WritLog()
        {
            Console.WriteLine(MailAddr);
        }
    }
    public class txtLog:Log
    {

    }
```
#    override(複寫) vs method hiding(方法遮蔽)
●基底類別&衍生類別可使用相同名稱與參數的方法，分為下列兩種使用方式
override(複寫)
```csharp=
 public class Log
    {
        public LogTypeDef LogType { get; set; }
        public string LogContent { get; set; }
        public DateTime LogTime { get; set; }
        public string MailAddr="abcd@gmail.com";
        public virtual void WriteLog()//父類別使用virtual關鍵字
        {
            if (this.LogType == LogTypeDef.SystemError)
            Console.WriteLine($"send email to: {MailAddr}");
            Console.WriteLine($"Base Log Show: {this.LogContent}");
        }
    }
    public class dbLog : Log
    {
        public override void WriteLog()//子類別使用override關鍵字
        {
            Console.WriteLine(MailAddr);
        }
    }
```
執行下列相同程式碼差異:
```csharp=
class Program
    {
        static void Main(string[] args)
        {
            Log log1 = new dbLog();
            Log log2 = new txtLog();
            log1.WriteLog();
            log2.WriteLog();
            Console.ReadLine();
        }
    }
```
![](https://i.imgur.com/6g6SQAq.png)
※基底類別可用來統整衍生類別，ex:List<T>
```csharp=
static void Main(string[] args)
        {
            Log log1 = new dbLog();
            Log log2 = new txtLog();
            var logs = new List<Log>();
            logs.Add(log1);
            logs.Add(log2);
            foreach (var item in logs)
            {
                item.WriteLog();
            }
            Console.ReadLine();
        }
```
執行效果相同↓
![](https://i.imgur.com/6g6SQAq.png)
***********************************************
method hiding(方法遮蔽)
```csharp=
 public class Log
    {
        public LogTypeDef LogType { get; set; }
        public string LogContent { get; set; }
        public DateTime LogTime { get; set; }
        public string MailAddr { get; set; }
        public void WriteLog()//父類別無關鍵字
        {
            if (this.LogType == LogTypeDef.SystemError)
            Console.WriteLine($"send email to{MailAddr}");
            Console.WriteLine(this.LogContent);
        }
    }
    public class dbLog : Log
    {
        public new void WriteLog()//子類別使用new關鍵字，不寫也會視為父類別方法遮蔽
        {
            Console.WriteLine(MailAddr);
        }
```
執行下列程式碼差異:
```csharp=
class Program
    {
        static void Main(string[] args)
        {
            Log log1 = new dbLog();
            Log log2 = new txtLog();
            log1.WriteLog();
            log2.WriteLog();
            Console.ReadLine();
        }
    }
```
![](https://i.imgur.com/aQn8EEi.png)

#    介面 Interface
##    介面是一種類別，原則上僅有規格內容，不會有方法實作(類似公版的概念)
```csharp=
public interface IPay
    {
       int Cal(int money);
    }
```
###    說明：
1.介面的命名：原則上會在前面加上"I"
![](https://i.imgur.com/NeyAEKn.png)
2.介面定義好後，除非必要，否則不應該再修改
3.如果一個類別繼承了介面，就必須依照介面的規格去撰寫(包含方法名稱與參數)
※可避免例如共同開發時，各自撰寫方法、參數等等不一致
```csharp=
public class StoreA:IPay
    {
        public int Cal(int money)
        {
            if (money >= 5000)
            {
                return money;
            }
            return money + 100;
        }
    }
```
4.一個Class可以繼承多個interface，使用","區隔，同時也可以繼承基底類別
ex:
```csharp=
public class StoreA:IPay,IPay2,IPay3
    {

    }
```
ex:
```csharp=
public class StoreA:BClass,IPay,IPay2,IPay3
    {

    }
```
練習-interface實作
```csharp=
class Program
    {
        static void Main(string[] args)
        {
            var Customer1 = new Customer();
            Customer1.StorePay = new StoreA();
            Console.WriteLine(Customer1.StorePay.Cal(5000));
            Console.ReadLine();
        }
    }
```
```csharp=
public class Customer
    {
        public string Name { get; set; }
        public IPay StorePay { get; set; }
    }
```
練習-interface建立(多種登入方式)
```csharp=
class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter Login Type:(1:FB,2:LINE,3:Google)");
            var authtype = Console.ReadLine();
            var auth = new UserAuth();
            switch (authtype)
            {
                case "1":
                    auth.DoLogin(new FBLogin());
                    break;
                case "2":
                    auth.DoLogin(new LineLogin());
                    break;
                case "3":
                    auth.DoLogin(new GoogleLogin());
                    break;
            }
            Console.ReadLine();
        }
    }
```
```csharp=
 public class UserAuth
    {
        public void DoLogin(ILogin login)
        {
            login.Login();
        }
    }
```
```csharp=
public interface ILogin
    {
        bool Login();
    }
```
```csharp=
        public class FBLogin : ILogin
        {
            public bool Login()
            {
                Console.WriteLine("Do FB Login");
                return true;

            }
        }
        public class LineLogin : ILogin
        {
            public bool Login()
            {
                Console.WriteLine("Do Line Login");
                return true;

            }
        }
        public class GoogleLogin : ILogin
        {
            public bool Login()
            {
                Console.WriteLine("Do Google Login");
                return true;

            }
        }
```
#    純文字txt檔案輸出、寫入、複製
##    輸出
```csharp=
Path.Combine() //將字串合併為路徑
```
```csharp=
File.ReadAllText(string path) //讀取檔案的所有文字，回傳string
```
```csharp=
File.ReadAllLines(string path) //讀取檔案所有行，回傳string[]
```
範例：
![](https://i.imgur.com/0sX3EhV.png)
```csharp=
using System.IO;

public class FileAccessDemo
    {
        public static void ReadFile()
        {
            string filepath = Path.Combine(@"C:\Users\User\Documents", "Demo.txt");
            string text = File.ReadAllText(filepath);

            Console.WriteLine("Txt Contents:{0} !!!", text);
            Console.WriteLine("====================分隔線====================");
            string[] lines = File.ReadAllLines(filepath);
            foreach (string line in lines)
            {
                Console.WriteLine("\t" + line);
            }
            Console.ReadLine();
        }
    }
```
```csharp=
class Program
    {
        static void Main(string[] args)
        {
            FileAccessDemo.ReadFile();
            Console.ReadLine();
        }
    }
```
![](https://i.imgur.com/96W8Yp6.png)
-
##    寫入
```csharp=
File.AppendAllLines(string path,string[]);//將字串陣列內容加在路徑檔案內容後方，不會覆寫
```
![](https://i.imgur.com/9LAG5tB.png)
```csharp=
File.WriteAllLines(string path,string[]); //將路徑檔案內容全部覆寫掉
```
![](https://i.imgur.com/vkasGxK.png)

```csharp=
public static void Write()
        {
            string filepath= Path.Combine(@"C:\Users\User\Documents", "Demo.txt");
            string[] lines = { "ABCDEFG", "HIJKLMN", "OPQRSTU", "VWXYZ" };
            File.WriteAllLines(filepath, lines);
            File.AppendAllLines(filepath, lines);
        }
```
```csharp=
   static void Main(string[] args)
        {
            FileAccessDemo.Write();
            Console.ReadLine();
        }
```
##    複製
```csharp=
//將路徑1檔案複製到路徑2檔案
//如果路徑2檔案已經存在，預設為不能覆寫(false)
File.Copy(string path1, string path2); 
```
![](https://i.imgur.com/Y0JmcyF.png)
```csharp=
//將路徑1檔案複製到路徑2檔案
//如果路徑2檔案已經存在，可設定是否能覆寫(true:能覆寫  false:不能覆寫)
File.Copy(string path1, string path2,bool overwrite); 
```
```csharp=
public static void Copy()
        {
            string filepath = Path.Combine(@"C:\Users\User\Documents", "Demo.txt");
            string targetfilepath= Path.Combine(@"C:\Users\User\Documents", "DemoCopy.txt");
            File.Copy(filepath, targetfilepath, true);//可覆寫目標路徑檔案
            File.Copy(filepath, targetfilepath, false);//不可覆寫，故執行會失敗

            //設定不可覆寫仍要能執行的方法：
            //if (File.Exists(targetPath))
            //{
            //    File.Delete(targetPath);
            //}
            //File.Copy(filePath, targetPath, false);
        }
```
```csharp=
static void Main(string[] args)
        {
            FileAccessDemo.Copy();
            Console.ReadLine();
        }
```
##    使用FileInfo + StreamReader輸出
```csharp=
public class FileInfoAccess
    {
        public static void ReadFile()
        {
            string filepath = Path.Combine(@"C:\Users\User\Documents", "Demo.txt");
            FileInfo myfile = new FileInfo(filepath);
            using (StreamReader sr= myfile.OpenText())
            {
                var str = string.Empty;
                while ((str=sr.ReadLine())!=null)
                {
                    Console.WriteLine(str);
                }
            }
        }
    }
```
##    使用FileInfo + StreamWriter寫入
```csharp=
public static void Write()
        {
            string filepath = Path.Combine(@"C:\Users\User\Documents", "Demo.txt");
            FileInfo myfile = new FileInfo(filepath);

            string[] lines = { "ABCDEFG", "HIJKLMN", "OPQRSTU", "VWXYZ" };

            using (StreamWriter sw=myfile.CreateText()) //覆寫路徑檔案內容
            {
                foreach (var item in lines)
                {
                    sw.WriteLine(item);
                }
            }

            using (StreamWriter sw = myfile.AppendText()) //內容新增在路徑檔案後方
            {
                foreach (var item in lines)
                {
                    sw.WriteLine(item);
                }
            }
        }
```
##    使用FileInfo複製
```csharp=
public  static void Copy()
        {
            string filepath = Path.Combine(@"C:\Users\User\Documents", "Demo.txt");
            string targetfilepath = Path.Combine(@"C:\Users\User\Documents", "DemoCopy.txt");

            FileInfo File1 = new FileInfo(filepath);
            if (!File1.Exists)
            {
                return;
            }
            else
            {
                FileInfo File2 = new FileInfo(targetfilepath);
                if (File2.Exists)
                {
                    File2.Delete();
                }
                File1.CopyTo(targetfilepath);
            }
        }
```