接口和抽象比较
有时候觉得自己的总结都重复了,但是现在觉得重复是增加印象的最好方式,另外要记住学习的目的是为了使用
接口的优点是他提供了一种让一个类成为两个子类的方式: 1个是继承,1个来自于接口,如果实现接口的类漏掉了
一个接口的方法,编译器会产生错误
代码From http://www.cnblogs.com/thcjp/archive/2007/04/11/709395.html
namespace I_B
{
public interface IBook
{
string BookName { get;set;} //声明接口中的属性
void InsertToDate(); //声明接口中的方法
}
public class Book : IBook
{ //我们声明这样一个类,他继承了接口IBook
string bookname;
public Book(string bn)
{
bookname = bn;
}
/**//// <summary>
/// 实现接口中的BookName属性
/// </summary>
public string BookName
{
get { return bookname; }
set { bookname = value; }
}
/**//// <summary>
/// 实现接口中声明的方法
/// </summary>
public void InsertToDate()
{
//将我们的信息写如数据库
}
}
}
对IBook的调用
protected void Page_Load(object sender, EventArgs e)
{
/**/////////////////////////////---接 口 一 演 示---////////////////////////
Book b = new Book("人性的优点");
lbl_bn.Text = GetS(b);
}
private static string GetS(IBook ib)
{//注意到这里,我们给的参数是我们的接口类型
return ib.BookName;
//这里返回的是我们的接口的属性
}
其他接口的使用: (接口是可以继承的)
interface I_2_A //声明第一个接口
{
int A { get;set;} //声明一个属性
}
interface I_2_B //声明第二个接口
{
int Count(int i,int j); //声明一个方法
}
interface I_2_C : I_2_A, I_2_B { } //声明第三个接口又继承了前两个接口
//什么都没有声明。但是他实际上是继承了前面两个接口的属性和方法。
public class I_2_L : I_2_C //声明一个类,他继承了I_2_C这个接口
{
int a;
public int A
{
get { return a; }
set { a = value; }
}
public int Count(int i, int j)
{
return i * j * a;
}
}
public interface I_3_A
{
int Count { get;set;}
int J(int j);
}
public interface I_3_B
{
void Count(int i);
double J(double j);
}
public interface I_3_C : I_3_A, I_3_B { }
public class I_3_L
{
public void Sum(I_3_C thc)
{
thc.Count(); //错误,具有二义性
thc.Count = 1; //错误,具有二义性
thc.Count(1); //错误,具有二义性
((I_3_A)thc).Count = 1; //正确
((I_3_B)thc).Count(1);
((I_3_A)thc).J(1);
((I_3_B)thc).J(1);
thc.J(1.0);
thc.J(1);
}
}
public interface I_4_A
{
string F(string A);
}
public interface I_4_B : I_4_A
{
new string F(string A);
}
public interface I_4_C : I_4_A
{
string T();
}
/**//// <summary>
/// 下面这个接口我们需要注意一下,他继承了B 和 C ,但是这两个有同时继承了 A
/// 不同的是,他们两个接口在内部定义的时候又采取了不同的策略,我们的访问该是如何的呢?
/// </summary>
public interface I_4_D : I_4_B, I_4_C { };
public class I_4_L
{
public string Test(I_4_D thc) //接受的参数类型为接口D类型的
{
thc.T(); //这个好理解,他直接调用 C接口的 T方法
thc.F("B接口的方法"); //这个呢就直接访问的B接口的F方法,虽然A接口也有一个F方法,但是他这里new了,就是说拦截了向上的访问
((I_4_A)thc).F("A接口的方法"); //通过明确指定的方法来访问A接口的F方法
((I_4_C)thc).F("A接口的方法"); //因为在C接口中并没有复写A接口的F方法,所以还是可以直接访问的
((I_4_D)thc).F("B接口的方法"); //同理是访问B接口的F方法,跟我们第二行的直接访问是一个道理
}
}
public abstract class vehicle
{//首先我们定义一个抽象的汽车基类
public int chelun; //车轮
public float zhongliang;
public vehicle(int cl,float zl)
{
chelun = cl;
zhongliang = zl;
}
public abstract string GetMore();
//定义一个抽象方法
}
public class car : vehicle
{//定义一个轿车类,继承自vehicel ,所以他必须实现父类中的所有抽象方法
public int passeng; //乘客数量
public car(int cl, float zl, int p)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
}
public override string GetMore()
{
//return 他的详细信息
}
}
public class Truck : vehicle
{
public int passeng; //乘客数量
public float load; //载重
public Truck(int cl, float zl, int p, float l)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
load = l;
}
public override string GetMore()
{
//return 卡车的全部信息
}
}
接口的优点是他提供了一种让一个类成为两个子类的方式: 1个是继承,1个来自于接口,如果实现接口的类漏掉了
一个接口的方法,编译器会产生错误
代码From http://www.cnblogs.com/thcjp/archive/2007/04/11/709395.html
namespace I_B
{
public interface IBook
{
string BookName { get;set;} //声明接口中的属性
void InsertToDate(); //声明接口中的方法
}
public class Book : IBook
{ //我们声明这样一个类,他继承了接口IBook
string bookname;
public Book(string bn)
{
bookname = bn;
}
/**//// <summary>
/// 实现接口中的BookName属性
/// </summary>
public string BookName
{
get { return bookname; }
set { bookname = value; }
}
/**//// <summary>
/// 实现接口中声明的方法
/// </summary>
public void InsertToDate()
{
//将我们的信息写如数据库
}
}
}
对IBook的调用
protected void Page_Load(object sender, EventArgs e)
{
/**/////////////////////////////---接 口 一 演 示---////////////////////////
Book b = new Book("人性的优点");
lbl_bn.Text = GetS(b);
}
private static string GetS(IBook ib)
{//注意到这里,我们给的参数是我们的接口类型
return ib.BookName;
//这里返回的是我们的接口的属性
}
interface I_2_A //声明第一个接口
{
int A { get;set;} //声明一个属性
}
interface I_2_B //声明第二个接口
{
int Count(int i,int j); //声明一个方法
}
interface I_2_C : I_2_A, I_2_B { } //声明第三个接口又继承了前两个接口
//什么都没有声明。但是他实际上是继承了前面两个接口的属性和方法。
public class I_2_L : I_2_C //声明一个类,他继承了I_2_C这个接口
{
int a;
public int A
{
get { return a; }
set { a = value; }
}
public int Count(int i, int j)
{
return i * j * a;
}
}
public interface I_3_A
{
int Count { get;set;}
int J(int j);
}
public interface I_3_B
{
void Count(int i);
double J(double j);
}
public interface I_3_C : I_3_A, I_3_B { }
public class I_3_L
{
public void Sum(I_3_C thc)
{
thc.Count(); //错误,具有二义性
thc.Count = 1; //错误,具有二义性
thc.Count(1); //错误,具有二义性
((I_3_A)thc).Count = 1; //正确
((I_3_B)thc).Count(1);
((I_3_A)thc).J(1);
((I_3_B)thc).J(1);
thc.J(1.0);
thc.J(1);
}
}
public interface I_4_A
{
string F(string A);
}
public interface I_4_B : I_4_A
{
new string F(string A);
}
public interface I_4_C : I_4_A
{
string T();
}
/**//// <summary>
/// 下面这个接口我们需要注意一下,他继承了B 和 C ,但是这两个有同时继承了 A
/// 不同的是,他们两个接口在内部定义的时候又采取了不同的策略,我们的访问该是如何的呢?
/// </summary>
public interface I_4_D : I_4_B, I_4_C { };
public class I_4_L
{
public string Test(I_4_D thc) //接受的参数类型为接口D类型的
{
thc.T(); //这个好理解,他直接调用 C接口的 T方法
thc.F("B接口的方法"); //这个呢就直接访问的B接口的F方法,虽然A接口也有一个F方法,但是他这里new了,就是说拦截了向上的访问
((I_4_A)thc).F("A接口的方法"); //通过明确指定的方法来访问A接口的F方法
((I_4_C)thc).F("A接口的方法"); //因为在C接口中并没有复写A接口的F方法,所以还是可以直接访问的
((I_4_D)thc).F("B接口的方法"); //同理是访问B接口的F方法,跟我们第二行的直接访问是一个道理
}
}
创建一个抽象类就是创建这样一个基类,他可以有一个或多个完整的,可以工作的方法,但是至少有一个方法未实现并声明为抽象的.不能实例话一个抽象类,而必须从他派生出类,这些类包含了抽象方法的实现过程.抽象类的作用是对派生类如何工作提供一个基类的定义,允许程序员在不同的派生类中填充这些实现过程
public abstract class vehicle
{//首先我们定义一个抽象的汽车基类
public int chelun; //车轮
public float zhongliang;
public vehicle(int cl,float zl)
{
chelun = cl;
zhongliang = zl;
}
public abstract string GetMore();
//定义一个抽象方法
}
public class car : vehicle
{//定义一个轿车类,继承自vehicel ,所以他必须实现父类中的所有抽象方法
public int passeng; //乘客数量
public car(int cl, float zl, int p)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
}
public override string GetMore()
{
//return 他的详细信息
}
}
public class Truck : vehicle
{
public int passeng; //乘客数量
public float load; //载重
public Truck(int cl, float zl, int p, float l)
: base(cl, zl)
{
chelun = cl;
zhongliang = zl;
passeng = p;
load = l;
}
public override string GetMore()
{
//return 卡车的全部信息
}
}
抽象类注意2点:抽象基类,和方法加abstract修饰,实现抽象类的同名方法用override描述
下面针对抽象类和接口做一个详细的对比
抽象类( abstract method ) 接口 ( interface )
可以包含实现区块 不能包含实现区块
可以包含抽象方法 不能包含抽象方法
可以包含非public成员 不可以包含非public成员
能继承其他的类,包含非抽象类 能继承其他接口
可以控制版本 无法控制版本
不能被实例化 不能被实例化