AI智能
改变未来

C#基础入门第十三天(多态接口)

第十二天复习

namespace 复习{class Program{static void Main(string[] args){/*Lisi<T>Dictionary<K,T>拆装箱装箱:值类型转为引用类型拆箱:引用类型转为值类型应该尽量避免在代码中发生文件流FileStream  StreamReader和StreamWrite多态:虚方法、抽象类、接口虚方法抽象类*///List<int> list = new List<int>();//Dictionary<int, string> dic = new Dictionary<int, string>();//dic.Add(1, \"张三\");//dic[2] = \"李四\";//foreach (KeyValuePair<int ,string> kv in dic)//{//    Console.WriteLine(\"{0}----{1}\", kv.Key, kv.Value);//}//Console.ReadKey();//File   FileStream  StreamReader  StreamWrite//using (FileStream fsRead = new FileStream(\"1.txt\", FileMode.OpenOrCreate, FileAccess.Read))//{//    byte[] buffer = new byte[1024 * 1024 * 5];//    int r = fsRead.Read(buffer, 0, buffer.Length);//    string s = Encoding.UTF8.GetString(buffer, 0, r);//    Console.WriteLine(s);//}//Console.ReadKey();//using (FileStream fsWrite = new FileStream(@\"C:\\Users\\Administrator\\Desktop\\new.txt\", FileMode.OpenOrCreate, FileAccess.Write))//{//    string s = \"今天的内容有点多啊\";//    byte[] buffer = Encoding.UTF8.GetBytes(s);//    fsWrite.Write(buffer, 0, buffer.Length);//}//Console.WriteLine(\"OK\");//Console.ReadKey();//虚方法和抽象类//老师可以起立,学生也可以起立,校长也可以起立//Person p = new Student();//p.StanUp();//Console.ReadKey();}}public abstract class Person{public abstract void StanUp();}public class Student : Person{public override void StanUp(){Console.WriteLine(\"学生起立,说老师好\");}}public class Teachar : Person{public override void StanUp(){Console.WriteLine(\"老师起立说校长好\");}}public class HeadMaster : Person{public override void StanUp(){Console.WriteLine(\"请坐\");}}

}

第十三天新内容
一、C#中的访问修饰符
public:公开的,公共的
private: 私有的,只能在当前类的内部访问
protected: 受保护的,只能在当前类的内部以及该类的子类中访问
internal:只能在当前程序集中访问,在同一个项目中和public的权限是一样的。
protected internal:protected和internal的权限相加

1.能够修饰类的访问修饰符只有:public和internal
2.可访问性不一致
子类的权限不能高于父类的权限,不然会暴露父类的成员

二、设计模式(设计这个项目的一种方式。)
简单工厂设计模式

namespace _03简单工厂设计模式{class Program{static void Main(string[] args){Console.WriteLine(\"请输入你需要的笔记本品牌\");string note = Console.ReadLine();NoteBook nb = GetNoteBook(note);nb.SayHello();Console.ReadKey();}/// <summary>/// 简单工厂的核心,根据用户输入的对象来赋值给父类/// </summary>/// <param name=\"note\"></param>/// <returns></returns>public static NoteBook GetNoteBook(string note){NoteBook nb = null;switch (note){case \"Lenove\" : nb = new Lenovo();break;case \"Acre\" : nb = new Acre();break;case \"Dell\" : nb = new Dell();break;case \"Hp\" : nb = new Hp();break;}return nb;}}public abstract class NoteBook{public abstract void SayHello();}public class Lenovo : NoteBook{public override void SayHello(){Console.WriteLine(\"我是联想笔记本,你连想都别想\");}}public class Acre : NoteBook{public override void SayHello(){Console.WriteLine(\"我是宏碁笔记本\");}}public class Dell : NoteBook{public override void SayHello(){Console.WriteLine(\"我是戴尔笔记本\");}}public class Hp : NoteBook{public override void SayHello(){Console.WriteLine(\"我是惠普笔记本\");}}}

三、值类型和引用类型的传递
值类型在复制的时候,传递时是这个值得本身
引用类型在复制的时候,传递的是对这个对象的引用

四、序列化和反序列化
序列化:将对象转换为二进制
反序列化:将二进制转换为对象
作用:传输数据
序列化:
1、将这个类标记为可以被序列化的,在类上面加关键字:[Serializable]

语法

namespace _04序列化和反序列化{class Program{static void Main(string[] args){////序列化//Person p = new Person();//p.Name = \"张三\";//p.Age = 18;//p.Gender = \'男\';//using (FileStream fsWrite = new FileStream(@\"C:\\Users\\Administrator\\Desktop\\111.txt\", FileMode.OpenOrCreate, FileAccess.Write))//{//    //开始序列化对象//    BinaryFormatter bf = new BinaryFormatter();//    bf.Serialize(fsWrite, p);//}//Console.WriteLine(\"写入成功\");//Console.ReadKey();//接收对方发送过来的二进制 反序列化成对象Person p;using (FileStream fsRead = new FileStream(@\"C:\\Users\\Administrator\\Desktop\\111.txt\", FileMode.OpenOrCreate, FileAccess.Read)){BinaryFormatter bf = new BinaryFormatter();p = (Person)bf.Deserialize(fsRead);}Console.WriteLine(p.Name);Console.WriteLine(p.Age);Console.WriteLine(p.Gender);Console.ReadKey();}}[Serializable]public class Person{private string _name;public string Name{get { return _name; }set { _name = value; }}private int _age;public int Age{get { return _age; }set { _age = value; }}private char _gender;public char Gender{get { return _gender; }set { _gender = value; }}}}

五、部分类
在同一个命名空间下写同名的类,关键字:partial
多用于多人开发时需要写一个类
语法

public partial class Person

六、密封类
不能够被继承,但是密封类能够继承其他类
语法
public sealed class Person

七、重写ToString方法
所有的东西都能ToString,应为ToString是Object的方法,所有的对象都是Object的子类
语法

namespace _05重写ToString方法{class Program{static void Main(string[] args){Person p = new Person();Console.WriteLine(p.ToString());Console.ReadKey();}}public class Person{public override string ToString(){return \"Hello word\";}}}

八、接口(接口就是一个规范,能力)
语法
[public] interface I…able
{
//接口中的成员不允许添加访问修饰符,默认就是public
//接口中,不允许具有方法体的函数,不能包含字段
//接口中,可以写自动属性(没写,但是编译时候会自动生成)
public int Age
{
get;
set;
}
成员…
}

接口的成员有:方法、自动属性、索引器 但是:自动属性本质也是两个函数,索引器也是函数。所以:接口的成员就有:方法

接口的特点:
接口是一种规范,只要一个类继承一个接口,这个类就必须实现这个接口中所有的成员

public class Person : IFyable{//实现这个接口中所有的成员public void Fly(){Console.WriteLine(\"飞\");}}public interface IFyable{void Fly();}

为了多态,接口不能被实例化。也就是说,接口不能new(不能创建对象)

static void Main(string[] args){//接口是不能被实例化的,因为接口中的成员没有方法体// IFyable fly = new IFyable();//如果要想实现多态,则需要指向一个对象IFyable fly = new Person();fly.Fly();Console.ReadKey();}

接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符默认为public,不能修改。接口中的成员不能有任何实现(“光说不练”,只是定义一组未实现的成员。类似于抽象类中的抽象函数)

接口中只能有方法、自动属性、索引器、事件,不能有“字段”和构造函数

接口与接口之间可以继承,并且可以多继承

public interface M1{void Test1();}public interface M2{void Test2();}public interface M3{void Test3();}public interface M4:M1,M2,M3{}public class Cat : M4{public void Test1(){throw new NotImplementedException();}public void Test2(){throw new NotImplementedException();}public void Test3(){throw new NotImplementedException();}}

接口并不能去继承一个类,而类可以继承接口(接口只能继承于接口,而类即可继承接口,也可继承类)
实现接口的子类,必须实现该接口的全部成员
一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承父类A。并实现接口接口IA,那么语法上A必须写在IA的前面
语法:
public class B:A,IA
{
类成员
}

由于全网这套视频在接口这里有问题,留待复习时候来搞

namespace _06接口{class Program{static void Main(string[] args){//接口是不能被实例化的,因为接口中的成员没有方法体// IFyable fly = new IFyable();//如果要想实现多态,则需要指向一个对象IFyable fly = new Person();fly.Fly();Console.ReadKey();}}public class Person : IFyable{//实现这个接口中所有的成员public void Fly(){Console.WriteLine(\"飞\");}}public interface IFyable{void Fly();}public interface M1{void Test1();}public interface M2{void Test2();}public interface M3{void Test3();}public interface M4:M1,M2,M3{}public class Cat : M4{public void Test1(){throw new NotImplementedException();}public void Test2(){throw new NotImplementedException();}public void Test3(){throw new NotImplementedException();}}}

九、显示实现接口(为了解决方法的重名问题)
语法及用法

namespace _07显示实现接口{class Program{static void Main(string[] args){IFlyable fly = new bird();fly.Fly();bird bi = new bird();bi.Fly();Console.ReadKey();}}public class bird:IFlyable{public void Fly(){Console.WriteLine(\"鸟会飞\");}/// <summary>/// 显示实现接口/// </summary>void IFlyable.Fly(){Console.WriteLine(\"我是接口的飞\");}}public interface IFlyable{void Fly();}}

总结:
1、什么时候用虚方法来实现多态
在提供出来的类中,能抽象出来一个父类,父类必须写上子类共有的方法,知道这个方法怎么写,并且还需要创建父类的对象,这时候就使用虚方法

2、什么时候用抽象类来实现多态
在提供出来的类中,能抽象出来一个父类,父类必须写上子类共有的方法,并且不知道这个方法怎么写,这时候就使用抽象类

3、什么时候用接口来实现多态
几个类中,找不出父类,但是他们都有一个共同的行为,就时候就使用接口

接口练习

namespace _08接口练习{class Program{static void Main(string[] args){//真的鸭子会游泳,木头鸭子不会游泳,橡皮鸭子会游泳ISwimming swim = new RealDuck();swim.Swim();Console.ReadKey();}}public class RealDuck : ISwimming{public void Swim(){Console.WriteLine(\"真的鸭子会游泳\");}}public class MuDuck{}public class XPDuck : ISwimming{public void Swim(){Console.WriteLine(\"橡皮鸭子漂着游泳\");}}public interface ISwimming{void Swim();}}

综合实战:超市收银系统

分析系统需求
超市提供的商品:笔记本电脑、手机、酱油、香蕉
商品在超市里面应该有:价格、数量、编号
这样就能抽象出来一个父类(ProductFather),包含价格(Price)、数量(Count)、编号(ID)

如果东西不够卖了,需要到仓库拿货物
仓库需要的功能:存储货物、提货、进货

超市卖东西时候需要一个收银的功能

抽象出一个商品的父类

class ProductFather{public decimal Price{get;set;}public double Count{get;set;}public string ID{get;set;}public ProductFather(string id, decimal price, double count){this.ID = id;this.Price = price;this.Count = count;}}

分别创建商品类继承于父类

class ShouJi:ProductFather{public ShouJi(string id, decimal price, double count) : base(id, price, count){}}

创建仓库类

class CangKu
{
//1.存储货物
//1.1 list相当于仓库,List<ProductFather>添加数据的集合,相当于将货架放到仓库,从而分门别类
List<List<ProductFather>> list = new List<List<ProductFather>>();

/// <summary>/// 想用户展示货物/// </summary>public void ShowPros(){foreach (var item in list){Console.WriteLine(\"仓库有:\" + item[0].Name + \",\" + \"\\t\" + \"有\" + item.Count + \"个,\" + \"\\t\" + \"每个\" + item[0].Price + \"元。\");}}/// <summary>/// 创建仓库对象时,向仓库中添加货架/// </summary>//list[0] 存电脑  list[1]存手机 list[2]存酱油 list[3]存香蕉,这时候如果多,就能通过循环来完成public CangKu(){list.Add(new List<ProductFather>());list.Add(new List<ProductFather>());list.Add(new List<ProductFather>());list.Add(new List<ProductFather>());}/// <summary>/// 进货/// </summary>/// <param name=\"strType\">货物的类型</param>/// <param name=\"count\">货物的数量</param>public void GetPros(string strType,int count){for (int i = 0; i < count; i++){switch (strType){case \"NoteBook\": list[0].Add(new NoteBook(Guid.NewGuid().ToString(), 5000, \"笔记本电脑\"));break;case \"ShouJi\":list[1].Add(new ShouJi(Guid.NewGuid().ToString(), 3000, \"手机\"));break;case \"JiangYou\":list[2].Add(new JiangYou(Guid.NewGuid().ToString(), 10, \"酱油\"));break;case \"Banana\":list[3].Add(new Banana(Guid.NewGuid().ToString(), 20, \"香蕉\"));break;}}}/// <summary>/// 取货/// </summary>/// <param name=\"strType\">货物的类型</param>/// <param name=\"count\">货物的数量</param>//货物取出后,需要放哪?而且有可能会拿很多个所以返回ProductFather[]public ProductFather[] QuPros(string strType, int count){ProductFather[] pros = new ProductFather[count];for (int i = 0; i < count; i++){switch (strType){case \"NoteBook\":if (list[0].Count == 0){Console.WriteLine(\"没有电脑了!\");}else{pros[i] = list[0][0];list[0].RemoveAt(0);}break;case \"ShouJi\":if (list[1].Count == 0){Console.WriteLine(\"没有手机了!\");}else{pros[i] = list[1][0];list[1].RemoveAt(0);}break;case \"JiangYou\":if (list[2].Count == 0){Console.WriteLine(\"没有酱油了!\");}else{pros[i] = list[2][0];list[2].RemoveAt(0);}break;case \"Banana\":if (list[3].Count == 0){Console.WriteLine(\"没有酱油了!\");}else{pros[i] = list[3][0];list[3].RemoveAt(0);}break;}}return pros;}}
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » C#基础入门第十三天(多态接口)