C# 理解接口和类
嗨,我知道这是一个很容易回答的问题,但是在阅读了下面的文章之后,我很难理解为什么需要使用界面。对于这里的基本问题很抱歉,但是当我把这个理论作为接口和类之间的契约时,我似乎看不出它有多有用。我知道它可以帮助你轻松地创建对象,但我觉得我遗漏了一些东西 我在这里和互联网上读了很多关于如何使用接口的帖子,但有一半的时间我觉得如果你创建一个类并继承它,它会不会做同样的事情?我错过了什么 一个场景,您(整个算法的创建者)根本不知道如何提前实现 要将其转换为现实生活场景,请执行以下操作: FxCop+StyleCop都使用访问者模式来扫描代码。因此,在本例中,工具(FxCop)的创建者拥有一些基本代码,这些代码与某些UI/CLI相耦合,并期望扫描结果中具有某些属性,如严重性/问题等 虽然FxCop附带默认规则,但作为最终客户,您也可以根据自己的喜好扩展这些规则。FxCop实现这一点的唯一方法是依赖polymorpishm接口/抽象类 因此,FxCop工具需要一个规则实例来检测某些东西并报告成功或失败 但是您的组织可能有一个只有您需要的自定义规则。假设它是这样的:我们所有的名称空间都必须以myorg.mytool开头 这是一个必须使用抽象的例子(不能只在类中预先实现代码),因为Microsoft对您在组织中实施的自定义代码规则一无所知 另一个例子是域驱动设计中域和基础结构代码的分离方式 那么,假设您有一个图书收藏应用程序。在那里你可以得到一本书,所有的书都是作者写的,等等 然后,您将有一个域类型调用,类似于BookRepository,您的所有书籍都将被持久化。这有两个方面:1。放置书籍所有处理逻辑的域和2。持久性代码(IO/数据库或其他) 将这两者分开的原因是,这样域逻辑(业务逻辑)就不会与持久性代码纠缠在一起。域代码不想知道一本书是如何持久化的。它只关心你能对一本书做些什么(通过作者获取、购买、出售等) 本例中的接口是在域代码中放置一个名为IBookRepository的接口,然后继续创建单元测试所需的所有代码。在这一点上,你不太关心书是如何存储的——你只关心它们是如何存储的。然后由另一个团队或更高的团队,您可以深入了解有关如何修复该书的详细信息。在数据库、缓存或其他地方。持久性代码也可以在不涉及域代码的情况下发展,域代码是持续发布原则的一个组成部分:尽可能小的更新。换句话说,它允许您根据业务代码发布基础架构更新。可能是你的应用程序运行得很好,但你不想更新数据库驱动程序 抽象类是介于接口和类之间的东西,但应该像接口一样使用/它们在使用上比类更接近接口 ** 最后,使用接口的另一个原因是,可以将接口视为方面,并且可以将多个接口(方面)应用于单个类(多重继承)几乎没有摩擦,而将其放在类中会迫使您执行单个继承,这可能会导致较大且过于复杂的继承层次结构C# 理解接口和类,c#,.net,vb.net,oop,C#,.net,Vb.net,Oop,嗨,我知道这是一个很容易回答的问题,但是在阅读了下面的文章之后,我很难理解为什么需要使用界面。对于这里的基本问题很抱歉,但是当我把这个理论作为接口和类之间的契约时,我似乎看不出它有多有用。我知道它可以帮助你轻松地创建对象,但我觉得我遗漏了一些东西 我在这里和互联网上读了很多关于如何使用接口的帖子,但有一半的时间我觉得如果你创建一个类并继承它,它会不会做同样的事情?我错过了什么 一个场景,您(整个算法的创建者)根本不知道如何提前实现 要将其转换为现实生活场景,请执行以下操作: FxCop+Styl
希望它能在本质上对您有所帮助,并且在每种情况下,我都能尽可能少地说几句话:
- 当您有不同的实体共享时,应使用摘要 普通行为
- 当您希望不同实体能够使用相同的代码
工作时,应使用接口
Animal
,其中包含一些字段NoLegs
,HasTail
,NoEyes
。
您创建了一个狗
、一个猫
和一个熊猫
类,所有这些都是从动物
继承的。
现在你有了3个类,但是在另外1个类中定义了共享代码,因为它们都有这些描述特征
现在进入界面:
在项目中的服务中,您创建了一个名为“StartRunning”的方法。
该方法的定义为:
public void StartRunning(List<ICanRun> thingsThatRun)
{
thingsThatRun.forEach(t => t.StartRunning());
}
我希望这个例子有助于为什么选择接口?
你开车吗?如果没有,我想你知道开车通常需要什么(方向盘、加速器、制动器)。答案的其余部分假设你驾驶一辆与我不同品牌的汽车
你开过我的车吗?没有。但是如果你有权限,你能不用学习如何驾驶我的车就可以驾驶我的车吗?是的。这同样适用于我。我从来没有开过你的车,但我可以不用学开车就能开 为什么呢因为所有汽车共享相同的界面。方向盘,右边是加速器,中间是刹车。没有两辆车是完全相同的,但它们的构造方式使驾驶员和任何一辆车的交互作用完全相同 将其与F16战斗机进行比较。驾驶汽车并不能让你驾驶喷气式飞机,因为它的界面不同。它没有方向盘,没有加速器/制动踏板 主要的好处很明显:驾驶员不需要学习如何单独驾驶每辆车 现在,为了完成这个类比
List<ICanRun> runableThings = new List<ICanRun>(){new Dog(), new Cat(), new Bike()};
StartRunning(runableThings);
public class BMW
{
public SteeringWheel SteeringWheel { get; set; }
public Pedal Accelerator { get; set; }
public Pedal Brake { get; set; }
}
public class BMWDriver
{
public void ParticipateInRace(BMW myBMW)
{
myBMW.Accelerator.Press();
myBMW.SteeringWheel.TurnLeft();
myBMW.SteeringWheel.TurnRight();
myBMW.Accelerator.Release();
myBMW.Brake.Press();
myBMW.Brake.Release();
}
}
public class Audi
{
public SteeringWheel SteeringWheel { get; set; }
public Pedal Accelerator { get; set; }
public Pedal Brake { get; set; }
}
public class AudiDriver
{
public void ParticipateInRace(Audi myAudi)
{
myAudi.Accelerator.Press();
myAudi.SteeringWheel.TurnLeft();
myAudi.SteeringWheel.TurnRight();
myAudi.Accelerator.Release();
myAudi.Brake.Press();
myAudi.Brake.Release();
}
}
public interface ICar
{
SteeringWheel SteeringWheel { get; }
Pedal Accelerator { get; }
Pedal Brake { get; }
}
public class BMW : ICar { /* same as before */ }
public class Audi : ICar { /* same as before */ }
public class Driver
{
public void ParticipateInRace(ICar anyCar)
{
anyCar.Accelerator.Press();
anyCar.SteeringWheel.TurnLeft();
anyCar.SteeringWheel.TurnRight();
anyCar.Accelerator.Release();
anyCar.Brake.Press();
anyCar.Brake.Release();
}
}
public class Runner
{
public void Run() { /* running logic */ }
}
public class Swimmer
{
public void Swim() { /* swimming logic */ }
}
public class Cyclist
{
public void Cycle() { /* cycling logic */ }
}
public class BasketBallPlayer : Runner
{
public void ThrowBall() { /* throwing logic */ }
// Running is already inherited from Runner
}
public class Triathlete: Runner, Swimmer, Cyclist { ... }
public interface IRunner
{
void Run();
}
public interface ISwimmer
{
void Swim();
}
public interface ICyclist
{
void Cycle();
}
public class Triathlete: IRunner, ISwimmer, ICyclist
{
public void Run() { /* running logic */ }
public void Swim() { /* swimming logic */ }
public void Cycle() { /* cycling logic */ }
}