using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1.code
{
/* 接口和抽象类
MSDN这样建议:
1.如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单易行的方法来控制组件版本。
通过更新基类,所有继承类都随更改自动更新。另一方面,接口一旦创建就不能更改。
如果需要接口的新版本,必须创建一个全新的接口。
2.如果创建的功能将在大范围的全异对象间使用,则使用接口。
抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。
3.如果要设计小而简练的功能块,则使用接口。如果要设计大的功能单元,则使用抽象类。
4.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。
抽象类允许部分实现类,而接口不包含任何成员的实现。
*/
class Program
{
static void Main(string[] args)
{
Dog myDog = new Dog();
myDog.Behavior(); //输出: "我白天活动,晚上睡觉"
Cat myCat = new Cat();
myCat.Behavior(); //输出: "我白天睡觉,晚上活动"
Console.ReadLine();
}
} //公共接口: "动物"
public interface IAnimal
{
void Behavior(); //行为方法,描述各种动物的特性
} //类: 狗
public class Dog : IAnimal
{
string AnimalName = "狗";
public void Behavior()
{
Console.WriteLine(AnimalName + ":我白天活动,晚上睡觉");
}
} //类: 猫
public class Cat : IAnimal
{
string AnimalName = "猫";
public void Behavior()
{
Console.WriteLine(AnimalName + ":我白天睡觉,晚上活动");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1.code
{
/* 接口介绍和使用
* 用来定义一种程序的协定。实现接口的类或者结构要与接口的定义严格一致。
* 有了这个协定,就可以抛开编程语言的限制(理论上)。
* C#接口可以从多个基接口继承,而类或结构可以实现多个接口。
* C#接口可以包含方法、属性、事件和索引器。接口本身不提供它所定义的成员的实现。
* 接口只指定实现该接口的类或接口必须提供的成员。
*/
class Program
{
static void Main(string[] args)
{
User user = new User();
Department dept = new Department(); //Ifactory factory =new SqlserverFactory();
IFactory factory = new AccessFactory(); //此时已经与具体的数据库访问解除了依赖
IUser iu = factory.CreateUser(); iu.Insert(user);
iu.GetUser(1); IDepartment id = factory.CreateDepartment(); id.Insert(dept);
id.GetDepartment(1); Console.Read();
}
} class User
{
private int id;
public int ID
{
get { return id; }
set { id = value; }
} } class Department
{
private int id;
public int ID
{
get { return id; }
set { id = value; }
} }
//IDepartment接口,用于客户端访问,解除与具体数据库访问的耦合。
interface IDepartment
{
void Insert(Department department); Department GetDepartment(int id);
} //SqlserverDepartment类,用于访问SQL Server的Department
class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在SQL Server 中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server 中根据ID得到Department表一条记录");
return null;
}
} //Access类,用于访问Access的Department
class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access 中给Department表增加一条记录");
} public Department GetDepartment(int id)
{
Console.WriteLine("在Access 中根据ID得到Department表一条记录");
return null;
} } //IUser接口,用于客户端访问,解除与具体数据库访问的耦合
interface IUser
{
void Insert(User user);
User GetUser(int id);
} //SqlserverUser类,用于访问SQL Server的User
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在SQL Server 中给User表增加一条记录");
} public User GetUser(int id)
{
Console.WriteLine("在SQL Server中根据ID得到User表一条记录");
return null;
}
} //Access类,用于访问Access的User
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access 中给User表增加一条记录"); }
public User GetUser(int id)
{
Console.WriteLine("在Access 中根据得到User表一条记录");
return null;
}
} //IFactory 接口,定义一个创建访问Department表对象的抽象的工厂接口
interface IFactory
{
IUser CreateUser();
//增加的接口方法
IDepartment CreateDepartment();
} //SqlServerFactory类,实现IFactory接口,实例化SqlserverUser和SqlserverDepartment
class SqlserverFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
} public IDepartment CreateDepartment()
{
return new SqlserverDepartment();
}
} //AccessFactory类,实现IFactory接口,实例化AccessUser和AccessDepartment
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
} public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1.code
{
/* 抽象类介绍和使用
* 抽象类是包含抽象方法的类。
* 那么什么又是抽象方法呢?抽象方法是没有方法内容的,只有一个方法名和参数列表的方法。
* 并以;结尾。为了标注他的与众不同,在他的返回类型前加abstract。并在class前加abstract。
* 简言之,由abstract修饰的方法和类就是抽象的方法和类。
*/
class Program
{
static void Main(string[] args)
{
//设置Context的初始状态为ConcreteStateA
Context c = new Context(new ConcreteStateA()); //不断的请求,同时更新状态
c.Request();
c.Request();
c.Request();
c.Request();
Console.Read();
}
} //Context类,维护一个COncreteState子类的实例,这个实例定义当前的状态
class Context
{
private State state;
//定义Context的初始状态
public Context(State state)
{
this.state = state;
} //可读写的状态属性,用于读取当前状态和设置新状态
public State State
{
get { return state; }
set
{
state = value;
Console.WriteLine("当前状态:" + state.GetType().Name);
}
} //对请求做处理,并设置下一状态
public void Request()
{
state.Handle(this);
} }
//抽象状态类State,定义一个接口以封装与Context的一个特定状态相关的行为
abstract class State
{
public abstract void Handle(Context context);
} //ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为
class ConcreteStateA : State
{
public override void Handle(Context context)
{
//设置ConcreteStateA的下一个状态是ConcreteStateB
context.State = new ConcreteStateB();
}
} class ConcreteStateB : State
{
public override void Handle(Context context)
{
//设置ConcreteStateB的下一个状态是ConcreteStateA
context.State = new ConcreteStateA();
}
}
}

接口与抽象类的相同点:


1、不能实例化;

2、包含未实现的方法声明;

3、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);

不过它们还是有很大的区别的

接口与抽象类的区别:



1.类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定

2.接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;

3.一个类一次可以实现若干个接口,但是只能扩展一个父类

4.接口可以用于支持回调,而继承并不具备这个特点.

5.抽象类不能被密封。

6.抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的.

7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上。

8.抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现。

9.好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。

10.尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知.(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则。

11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法.

什么时候使用抽象类和接口

1. 如果预计要创建组件的多个版本,则创建抽象类。抽象类提供简单的方法来控制组件版本。

2.如果创建的功能将在大范围的全异对象间使用,则使用接口。如果要设计小而简练的功能块,则使用接口。

3.如果要设计大的功能单元,则使用抽象类.如果要在组件的所有实现间提供通用的已实现功能,则使用抽象类。

4.抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

 

下面有几个比喻说的很贴切,大家从中也许也会领悟很多



1.飞机会飞,鸟会飞,他们都继承了同一个接口“飞”;但是F22属于飞机抽象类,鸽子属于鸟抽象类。

2.就像铁门木门都是门(抽象类),你想要个门我给不了(不能实例化),但我可以给你个具体的铁门或木门(多态);而且只能是门,你不能说它是窗(单继承);一个门可以有锁(接口)也可以有门铃(多实现)。门(抽象类)定义了你是什么,接口(锁)规定了你能做什么(一个接口最好只能做一件事,你不能要求锁也能发出声音(接口污染))。

c#接口和抽象类比较的更多相关文章

  1. 从接口、抽象类到工厂模式再到JVM来总结一些问题

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习! 涉及到的知识点总结如下: 为什么使用接口? 接口和抽象类的区别 简单工厂模式总结 Java中new和newInstance的区别 J ...

  2. (转)深入理解Java的接口和抽象类

    原文地址: http://www.cnblogs.com/dolphin0520/p/3811437.html 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP ...

  3. c++ 接口和抽象类

    其实对抽象类与接口的区别一直是搞不太清楚,最近正在学习<设计模式>,期间用到了很多c++多态的知识.这是才恍然发现,是应该整理下这方面的知识了.但在翻阅书本.上网查阅资料之际,发现有篇文章 ...

  4. android中接口和抽象类的区别

    最近发现很多基础有点生疏了,特地写一点博客来巩固一下.今天主要来谈谈接口和抽象类的区别,我们在项目的很多地方都会用到接口或者抽象类,但是它们之间的一些区别和相同点不知道大家有没有注意到,还有就是,什么 ...

  5. 深入理解Java的接口和抽象类(转)

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...

  6. c#接口与抽象类的区别

    abstract 修饰符用于表示所修饰的类是不完整的,并且它只能用作基类.抽象类与非抽象类在以下方面是不同的: 抽象类不能直接实例化,并且对抽象类使用 new 运算符是编译时错误.虽然一些变量和值在编 ...

  7. Java接口和抽象类的区别

    今天看到项目中,写了一个抽象类,里面有很多方法继承了这类,当调用这个接口时,采用的是这个抽象类去调方法的,当时一想,这个不就是我们说的Java的多态的特征: 继承:存在继承关系的子类和父类 重写:子类 ...

  8. 深入理解Java的接口和抽象类

    深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的 ...

  9. C#基础系列——一场风花雪月的邂逅:接口和抽象类

    前言:最近一个认识的朋友准备转行做编程,看他自己边看视频边学习,挺有干劲的.那天他问我接口和抽象类这两个东西,他说,既然它们如此相像, 我用抽象类就能解决的问题,又整个接口出来干嘛,这不是误导初学者吗 ...

  10. [Think In Java]基础拾遗1 - 对象初始化、垃圾回收器、继承、组合、代理、接口、抽象类

    目录 第一章 对象导论第二章 一切都是对象第三章 操作符第四章 控制执行流程第五章 初始化与清理第六章 访问权限控制第七章 复用类第九章 接口 第一章 对象导论 1. 对象的数据位于何处? 有两种方式 ...

随机推荐

  1. 汇编指令-bic(位清除)、orr(位或)(3)

    1. bic  (Bit Clear)位清除指令bic指令的格式为:bic{条件}{S}  Rd,Rn,operand bic指令将Rn 的值与操作数operand2 的反码按位逻辑"与&q ...

  2. Python输入输出练习,运算练习,turtle初步练习

    Hello World! 简单交互(交互式,文件式)教材P19 radius=25 area=3.1415*radius*radius print(area) print('{:.2f}'.forma ...

  3. 线程高级篇-读写锁ReentrantReadWriteLock

    转载原文:http://blog.csdn.net/john8169/article/details/53228016 读写锁: 分为读锁和写锁,多个读锁不互斥,读锁和写锁互斥,这是有JVM自己控制的 ...

  4. 201521123039 《java程序设计》第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 总结: 1.集合可以动态修改大小,但是不可以存放基本数据类型: 2.java中任何对象都是is-a Objec ...

  5. 201521123122 《java程序设计》 第五周实验总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过? ...

  6. 201521123023《Java程序设计》第五周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 2. 书面作业 Q1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.java文件能否编译通过 ...

  7. 201521123113 《Java程序设计》第3周学习总结

    1. 本周学习总结 2.书面作业 Q1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...

  8. 201521123093 java 第二周学习总结

    201521123093 <java程序设计> 第二周学习总结 一.第二周学习总结 答:(1)关于进一步使用码云管理代码,本周才真正学会了如何将Eclipse里的代码上传到码云中,并且能够 ...

  9. 201521123072《java程序设计》第九周总结

    201521123072<java程序设计>第九周总结 1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 常用异常 题目5-1 1.1 截 ...

  10. Python爬虫2----------运用代理访问

    为request添加一个代理,及将浏览器头部信息加入,随机从ip列表中拿出一个ip进行访问 注意函数参数的形式,如request.proxyhandler(协议,地址) import urllib.r ...