舞蹈网站建设报价,济南网站建设飞鸟,友链提交入口,租服务器 wordpress目录
一、抽象类 1.示例
二、抽象方法
三、接口
1.示例
2.内联表达治愈警告CA1859
#xff08;1#xff09;传统程序书写源码
#xff08;2#xff09;内联后的源码
四、多重继承
1.示例
五、显式接口成员实现
1.示例
六、总结 赠人玫瑰#xff0c;手有余香1传统程序书写源码
2内联后的源码
四、多重继承
1.示例
五、显式接口成员实现
1.示例
六、总结 赠人玫瑰手有余香 留下心得换点流量。
一、抽象类 一般将父类定义为抽象类需要使用这个父类进行继承与多态处理。C#中声明抽象类时需要使用abstract关键字声明抽象类时除abstract关键字、class关键字和类名外其他的都是可选项。 抽象类除了被继承之外没有任何意义。 1.示例
//抽象类、抽象方法
namespace _01
{public abstract class MyClass{private string id ;private string name ;/// summary/// 编号属性及实现/// /summarypublic string ID{get{return id;}set{id value;}}/// summary/// 姓名属性及实现/// /summarypublic string Name{get{return name;}set{name value;}}/// summary/// 抽象方法用来输出信息/// /summarypublic abstract void ShowInfo();}public class DriveClass : MyClass //继承抽象类{/// summary/// 重写抽象类中输出信息的方法/// /summarypublic override void ShowInfo(){Console.WriteLine(ID Name);}}class Program{/// summary/// 内联/// /summarystatic void Main(string[] args){DriveClass driveclass new(); //实例化派生类,内联前用派生类对象实例化抽象类 ((DriveClass)driveclass).ID BH0001; //使用抽象类对象访问抽象类中的编号属性((DriveClass)driveclass).Name TM; //使用抽象类对象访问抽象类中的姓名属性((DriveClass)driveclass).ShowInfo(); //使用抽象类对象调用派生类中的方法Console.WriteLine(------------);driveclass.ID BH0001; //派生类直接实例化driveclass.Name TM;driveclass.ShowInfo();Console.Read();}}
}//结果
/*BH0001 TM
---------------
BH0001 TM*/二、抽象方法 在抽象类中声明方法时如果加上abstract关键字则为抽象方法。 使用abstract关键字定义的类称为抽象类而使用这个关键字定义的方法称为抽象方法抽象方法没有方法体这个方法本身没有任何意义除非它被重写而承载这个抽象方法的抽象类就必须被继承。反之如果声明一个抽象的方法就必须将承载这个抽象方法的类定义为抽象类不可能在非抽象类中获取抽象方法。只要类中有一个抽象方法此类就被标记为抽象类。 抽象类被继承后需要实现其中所有的抽象方法也就是保证相同的方法名称、参数列表和相同返回值类型创建出非抽象方法当然也可以是抽象方法。继承抽象类的所有子类需要将抽象类中的抽象方法进行覆盖。
声明抽象方法时需要注意以下两点
☑ 抽象方法必须声明在抽象类中。
☑ 声明抽象方法时不能使用virtual、static和private修饰符。 抽象方法声明引入了一个新方法但不提供该方法的实现由于抽象方法不提供任何实际实现因此抽象方法的方法体只包含一个分号。 当从抽象类派生一个非抽象类时需要在非抽象类中重写抽象方法以提供具体的实现重写抽象方法时使用override关键字。
三、接口 接口是抽象类的延伸可以将它看作是纯粹的抽象类接口中的所有方法都没有方法体。接口可由方法、属性、事件和索引器或这4种成员类型的任何组合构成但不能包含字段也不能设置这些成员的具体值即只能定义不能给它们赋值。 接口可以继承其他接口。
接口具有以下特征
☑ 接口类似于抽象基类继承接口的任何非抽象类型都必须实现接口的所有成员。
☑ 不能直接实例化接口。
☑ 接口可以包含事件、索引器、方法和属性。
☑ 接口不包含方法的实现。
☑ 类和结构可从多个接口继承。
☑ 接口自身可从多个接口继承。
1.示例
// 接口
namespace _02
{interface IMyInterface{/// summary/// 编号可读可写/// /summarystring ID{get;set;}/// summary/// 姓名可读可写/// /summarystring Name{get;set;}/// summary/// 显示定义的编号和姓名/// /summaryvoid ShowInfo();}class Program : IMyInterface //继承自接口{string id ;string name ;/// summary/// 编号/// /summarypublic string ID{get{return id;}set{id value;}}/// summary/// 姓名/// /summarypublic string Name{get{return name;}set{name value;}}/// summary/// 显示定义的编号和姓名/// /summarypublic void ShowInfo(){Console.WriteLine(编号\t 姓名);Console.WriteLine(ID \t Name);}/// summary/// 注释掉的部分警告CA1859/// 内联临时变量后警告消失/// /summarystatic void Main(string[] args){Program program new(); //实例化Program类对象//IMyInterface Imyinterface program; //使用派生类对象实例化接口ImyInterface//Imyinterface.ID TM; //为派生类中的ID属性赋值//Imyinterface.Name C#从入门到精通; //为派生类中的Name属性赋值//Imyinterface.ShowInfo();((IMyInterface)program).ID TM; //为派生类中的ID属性赋值((IMyInterface)program).Name C#从入门到精通;//为派生类中的Name属性赋值((IMyInterface)program).ShowInfo(); //调用派生类中方法显示定义的属性值Console.WriteLine(----------------------); //用子类派生类直接实例化program.ID TM;program.Name C#从入门到精通;program.ShowInfo();Console.Read();}}
}//运行结果
/*
编号 姓名
TM C#从入门到精通
----------------------
编号 姓名
TM C#从入门到精通*/
2.内联表达治愈警告CA1859 上述示例中传统的Main()方法中先实例化派生类Program再用派生对象实例化接口然后用接口的属性为派生类属性赋值。这是.NET Framework 4.8之前的做法其缺点是程序表达晦涩不易读继承关系不明显。 在.NET 7.0、.NET 8.0下不建议这样表达会提示警告CA1859。VS2022.NET 8.0快速重构建议给出的意见是用内联临时变量的方法直接表达继承关系使得程序简洁易读继承关系清晰明了。 严重性 代码 说明 项目 文件 行 禁止显示状态 消息 CA1859 将变量“_Imyinterface”的类型从“_02.IMyInterface”更改为“_02.Program”以提高性能 02 E:\C#_TM\chapter17\02\Program.cs 72 活动
1传统程序书写源码
static void Main(string[] args)
{Program program new(); //实例化Program类对象IMyInterface Imyinterface program; //使用派生类对象实例化接口ImyInterfaceImyinterface.ID TM; //为派生类中的ID属性赋值Imyinterface.Name C#从入门到精通; //为派生类中的Name属性赋值Imyinterface.ShowInfo(); //调用派生类中方法显示定义的属性值Console.WriteLine(------------------);//用子类派生类直接实例化program.ID TM;program.Name C#从入门到精通;program.ShowInfo();Console.Read();
}
2内联后的源码
static void Main(string[] args){Program program new(); //实例化Program类对象//使用派生类对象实例化接口 ((IMyInterface)program).ID TM; //为派生类中的ID属性赋值((IMyInterface)program).Name C#从入门到精通; //为派生类中的Name属性赋值((IMyInterface)program).ShowInfo(); //调用派生类中方法显示定义的属性值Console.WriteLine(----------------------); //用子类派生类直接实例化program.ID TM;program.Name C#从入门到精通;program.ShowInfo();Console.Read();}内联的表达可以隐藏舍去 结果是一样的只是继承关系不再明显可见了。 后面的例子中都会出现CA1859警告其处理方法同此例不再重复讲述。
四、多重继承 可以只继承一个接口接口也可以多重继承使用多重继承时要继承的接口之间用逗号“,”分隔。
1.示例
// 继承多个接口
namespace _03
{interface IPeople{/// summary/// 姓名/// /summarystring Name{get;set;}/// summary/// 性别/// /summarystring Sex{get;set;}}interface ITeacher : IPeople //继承公共接口{/// summary/// 教学方法/// /summaryvoid Teach();}interface IStudent : IPeople //继承公共接口{/// summary/// 学习方法/// /summaryvoid Study();}class Program : IPeople, ITeacher, IStudent//多接口继承{string name ;string sex ;/// summary/// 姓名/// /summarypublic string Name{get{return name;}set{name value;}}/// summary/// 性别/// /summarypublic string Sex{get{return sex;}set{sex value;}}/// summary/// 教学方法/// /summarypublic void Teach(){Console.WriteLine(Name Sex 教师);}/// summary/// 学习方法学习内联的表达/// 内联前用派生类对象实例化接口ITeacher/// 内联前用派生类对象实例化接口IStudent/// 舍去内联的表达后效果一样内联的存在使得继承关系清晰明了/// /summarypublic void Study(){Console.WriteLine(Name Sex 学生);}static void Main(string[] args){Program program new(); //实例化类对象内联表达((ITeacher)program).Name TM;((ITeacher)program).Sex 男;((ITeacher)program).Teach();((IStudent)program).Name C#;((IStudent)program).Sex 男;((IStudent)program).Study();Console.WriteLine(--舍去内联--);program.Name TM;program.Sex 男;program.Teach();program.Name C#;program.Sex 男;program.Study();Console.Read();}}
}//运行结果
/*
TM 男 教师
C# 男 学生
--舍去内联--
TM 男 教师
C# 男 学生 */
五、显式接口成员实现 如果类实现两个接口并且这两个接口包含具有相同签名的成员那么在类中实现该成员将导致两个接口都使用该成员作为它们的实现。然而如果两个接口成员实现不同的功能则可能会导致其中一个接口的实现不正确或两个接口的实现都不正确这时可以显式地实现接口成员即创建一个仅通过该接口调用并且特定于该接口的类成员。显式接口成员实现是使用接口名称和一个句点命名该类成员来实现的。 显式接口成员实现中不能包含访问修饰符、abstract、virtual、override或static修饰符。 显式接口成员属于接口的成员而不是类的成员因此不能使用类对象直接访问只能通过接口对象来访问。 使用场合当继承多个接口的类中欲实现来自各自接口的同名方法赋予不同的功能时。
1.示例
// 显式接口成员实现
namespace _04
{interface IMyInterface1{/// summary/// 求和方法/// /summaryint Add();}interface IMyInterface2{/// summary/// 求和方法/// /summaryint Add();}/// summary/// 显式接口成员实现/// /summaryclass MyClass : IMyInterface1, IMyInterface2 //继承接口{/// summary/// 求和方法1/// /summaryint IMyInterface1.Add() //显式接口成员实现{int x 3;int y 5;return (x y);}/// summary/// 求和方法2/// /summaryint IMyInterface2.Add() //显式接口成员实现{int x 3;int y 5;int z 7;return (x y z);}}class Program{static void Main(string[] args){MyClass myclass new(); //实例化接口继承类的对象IMyInterface1 imyinterface1 myclass; //使用接口继承类的对象实例化接口Console.WriteLine(imyinterface1.Add()); //使用接口对象调用接口中的方法IMyInterface2 imyinterface2 myclass; //使用接口继承类的对象实例化接口Console.WriteLine(imyinterface2.Add()); //使用接口对象调用接口中的方法Console.WriteLine(----内联表达----); //使用内联表达是不是更清晰易读Console.WriteLine(((IMyInterface1)myclass).Add()); Console.WriteLine(((IMyInterface2)myclass).Add());Console.Read();}}
}//运行结果
/*
8
15
----内联表达----
8
15 */ 内联表达用最少的语句实现最清晰的继承关系表达是不是你的最爱
六、总结 抽象类和接口都包含可以由派生类继承的成员它们都不能直接实例化但可以声明它们的变量。如果这样做就可以使用多态性把继承这两种类型的对象指定给它们的变量。 抽象类和接口这两种类型用于完全不同的目的。抽象类主要用作对象系列的基类共享某些主要特性例如共同的目的和结构。接口则主要用于类这些类在基础水平上有所不同但仍可以完成某些相同的任务。
抽象类和接口的区别主要有以下几点
☑ 它们的派生类只能继承一个基类即只能直接继承一个抽象类但可以继承任意多个接口。
☑ 抽象类中可以定义成员的实现但接口中不可以。
☑ 抽象类中可以包含字段、构造函数、析构函数、静态成员或常量等接口中不可以。
☑ 抽象类中的成员可以是私有的只要它们不是抽象的、受保护的、内部的或受保护的内部成员受保护的内部成员只能在应用程序的代码或派生类中访问但接口中的成员必须是公共的。
☑ 派生类必须继承抽象类的全部。派生类可以选择是否继承接口。
☑ 抽象类使得所有派生类大同小异继承多个接口则使得派生类各有不同。