1、 接口
l 接口的特征:
(1) 接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员。
(2) 不能直接实例化接口
(3) 接口可以包含事件、索引器、方法和属性
(4) 接口不包含方法的实现
(5) 类和结构可以从多个接口继承
(6) 接口自身可以从多个接口继承
l 可以用new、public、protected、internal、private等修饰符声明接口,但接口成员必须是公共的。
l 显示接口成员实现:是使用接口名称和一个句点命名该类成员来实现的。例:
namespace _10._1._3显示接口成员实现
{
interface ImyInterface1
{
int Add();
}
interface ImyInterface2
{
int Add();
}
class myClass : ImyInterface1, ImyInterface2
{
/// <summary>
/// 求和方法
/// </summary>
/// <returns>加法运算的和</returns>
int ImyInterface1.Add() //显示接口成员实现
{
int x = 3;
int y = 5;
return x + y;
}
/// <summary>
/// 求和方法
/// </summary>
/// <returns>加法运算的和</returns>
int 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 myClass();
ImyInterface1 imyinterface1 = myclass; //使用接口继承类的对象实例化接口
Console.WriteLine(imyinterface1.Add());//使用接口对象调用接口中的方法
ImyInterface2 imyinterface2 = myclass;
Console.WriteLine(imyinterface2.Add());
}
}
}
注意:(1)显示接口成员实现中不能包含访问修饰符、abstract、virtual、override或static修饰符。(2)显示接口成员属于接口的成员,而不是类的成员,因此,不能使用类对象直接访问,只能通过接口对象来访问。
2、 抽象类与抽象方法
l 与非抽象类的主要区别:
(1) 抽象类不能直接实例化
(2) 抽象类中可以包含抽象成员,但非抽象类中不可以
(3) 抽象类不能被密封
l 在抽象类中声明方法时,如果加上abstract关键字,则为抽象方法。声明抽象方法时,不能使用virtual、static和private修饰符。
当从抽象类派生一个非抽象类时,需要在非抽象类中重写抽象方法,以提供具体的实现,重写抽象方法时使用override关键字。
l 运用举例:
namespace _10._2._3抽象类与抽象方法的使用
{
public abstract class myClass
{
private stringid = "";
private string name = "";
public stringID
{
get
{
return id;
}
set
{
id = value;
}
}
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public abstract void ShowInfo();
}
public class DriveClass : myClass
{
public override void ShowInfo() //重写抽象类中输出信息的方法
{
Console.WriteLine(ID + " " + Name);
}
}
class Program
{
static void Main(string[] args)
{
DriveClass driveclass = new DriveClass(); //实例化派生类
myClass myclass = driveclass; //使用派生类对象实例化抽象类
myclass.ID = "BH0001";
myclass.Name = "TM";
myclass.ShowInfo(); //使用抽象类对象调用派生类中的方法
}
}
}
l 抽象类与接口的区别主要有一下几点:
(1) 它们的派生类只能继承一个基类,即只能直接继承一个抽象类,但可以继承任意多个接口。
(2) 抽象类中可以定义成员的实现,但接口中不可以。
(3) 抽象类中可以包含字段、构造函数、析构函数、静态成员或常量等,但接口中不可以。
(4) 抽象类中的成员可以是私有的(只要它们不是抽象的)、受保护的、内部的或受保护的内部成员(受保护的内部成员只能在应用程序代码或派生类中访问),但接口中的成员必须是公共的。
说明:
抽象类和接口这两种类型用于完全不同的目的。抽象类主要用作对象系列的基类,共享某些主要特性,例如共同的目的和结构。接口则主要用于类,这些类在基础水平上有所不同,但仍可以完成某些相同的任务。
3、 密封类与密封方法
密封类可以用来限制扩展性,如果密封了某个类,则其他类不能从该类继承:如果密封了某个成员,则派生类不能重写该成员的实现。
l C#中使用密封类时,如果类满足如下条件,则应将其密封:
(1) 类是静态类
(2) 类包含带有安全敏感信息的继承的受保护成员
(3) 类继承多个虚成员,并且密封每个成员的开发和测试开销明显大于密封整个类
(4) 类是一个要求使用反射进行快速搜索的属性。密封属性可以提高反射在检索属性时的性能
说明:
(1) 密封类不能作为基类被继承,但它可以继承别的类或接口
(2) 在密封类中不能声明受保护成员或虚成员,因为受保护成员只能从派生类进行访问,而虚成员只能在派生类中重写
(3) 由于密封类的不可继承性,因此密封类不能声明为抽象的,即sealed修饰符不能与abstract修饰符同时使用
l 密封方法概述及声明:
并不是每个方法都可以声明为密封方法,密封方法只能用于对基类的虚方法进行实现,并提供具体的实现。所以,声明密封方法时,sealed修饰符总是和override修饰符同时使用。例:
public class myClass1
{
publicvirtual void Method()
{
Console.WriteLine(“基类中的虚方法”);
}
}
public sealed class myClass2:myClass1
{
publicsealed override void Method() //密封并重写基类中的虚方法Method
{
base.Method(); //base关键字主要是为派生类调用基类成员提供一种简写的方法
Console.WriteLine(“密封类中重写后的方法”);
}
}
l 密封类和密封方法的使用:
密封类除了不能被继承外,与非密封类的用法大致相同,而密封方法则必须通过重写基类中的虚方法来实现。
namespace _10._3._3密¨¹封¤a类¤¨¤与®?密¨¹封¤a方¤?法¤¡§的Ì?使º1用®?
{
public class myClass1
{
public virtual voidShowInfo() //虚¨¦方¤?法¤¡§,ê?用®?来¤¡ä显?示º?信?息¡é
{
}
}
public sealed class myClass2 : myClass1 //密¨¹封¤a类¤¨¤,ê?继¨¬承D自Á?myClass1
{
privatestring id = ""; //string类¤¨¤型¨ª变À?量¢?,ê?用®?来¤¡ä记?录?编À¨¤号?
privatestring name = ""; //string类¤¨¤型¨ª变À?量¢?,ê?用®?来¤¡ä记?录?名?称?
public string ID
{
get
{
returnid;
}
set
{
id = value;
}
}
public string Name
{
get
{
returnname;
}
set
{
name = value;
}
}
public sealed override void ShowInfo() //密¨¹封¤a并¡é重?写¡ä基¨´类¤¨¤中D的Ì?ShowInfo方¤?法¤¡§
{
Console.WriteLine(ID+ " " + Name);
}
}
class Program
{
static void Main(string[] args)
{
myClass2myclass2 = new myClass2();//实º¦Ì例¤y化¡¥密¨¹封¤a类¤¨¤对?象¨®
myclass2.ID = "BH0001";
myclass2.Name = "TM";
myclass2.ShowInfo();
Console.ReadKey();
}
}
}