我有一个抽象类,一个接口和一个继承了抽象类和接口的类。
我想从继承类的抽象类中公开该方法。我该如何实现?
public abstract class CustomerServiceBase
{
public string GetName()
{
return "John Doe";
}
}
public interface ICustomerService
{
void DoOtherStuff();
}
public class CustomerService : CustomerServiceBase, ICustomerService
{
public void DoOtherStuff()
{
//Code removed for brevity
}
}
public class Start
{
public void Go()
{
ICustomerService _customerService = new CustomerService();
_customerService.DoOtherStuff();
var name = _customerService.GetName();//This won't compile
}
}
更新
道歉,我添加了准确显示这种情况的其他代码,即使用Autofac将依赖项注入到Asp.Net MVC控制器中,然后使用服务类来执行任务。
public abstract class CustomerServiceBase
{
public string GetName()
{
return "John Doe";
}
}
public interface ICustomerService
{
void DoOtherStuff();
}
public class CustomerService : CustomerServiceBase, ICustomerService
{
public void DoOtherStuff()
{
//Code removed for brevity
}
}
public static class AutofacConfig
{
public static IContainer Register(IAppBuilder app)
{
var builder = new ContainerBuilder();
ConfigureServices(builder);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
SetBothDependencyResolvers(container);
return container;
}
public static void ConfigureServices(ContainerBuilder builder)
{
builder.RegisterType<CustomerService>().AsImplementedInterfaces().InstancePerLifetimeScope();
}
}
public class CustomerController : Controller
{
protected readonly ICustomerService _customerService;
public CustomerController(ICustomerService customerService)
{
this._customerService = customerService;
}
public ActionResult Index()
{
_customerService.DoOtherStuff();
var name = _customerService.GetName();
return View();
}
}
结果(基于接受的答案)
public abstract class CustomerServiceBase : ICustomerService
{
public abstract void DoOtherStuff();
//You could mark this as virtual if you want the option to override functionality
public string GetName()
{
return "John Doe";
}
}
public interface ICustomerService
{
void DoOtherStuff();
string GetName();
}
public class CustomerService : CustomerServiceBase
{
public override void DoOtherStuff()
{
//Code removed for brevity
}
}
public class CustomerController : Controller
{
protected readonly ICustomerService _customerService;
public CustomerController(ICustomerService customerService)
{
this._customerService = customerService;
}
public ActionResult Index()
{
_customerService.DoOtherStuff();
var name = _customerService.GetName();
return View();
}
}
答案 0 :(得分:3)
只需更改变量的类型。自该类实现以来,您仍然可以调用ICustomerService的成员。
public void Go()
{
CustomerService _customerService = new CustomerService();
_customerService.DoOtherStuff();
var name = _customerService.GetName();
}
答案 1 :(得分:1)
我想从继承类的抽象类中公开该方法。我该如何实现?
这已经发生。出现编译器错误的原因是您拥有的代码将_customerService
指定为类型(接口)ICustomerService
,并且此接口没有方法DoOtherStuff()
的定义。如果要使用类型CustomerService
,则可以调用在此类型继承的抽象类(或它实现的接口)上定义的方法。
CustomerService _customerService = new CustomerService();
_customerService.DoOtherStuff();
var name = _customerService.GetName(); // compiles just fine
关于问题的标题:
在接口上继承抽象类方法
这是不可能的(在c#中)。接口可以扩展其他接口并由类实现,但是一个接口不能“继承”另一个接口以外的任何东西(尽管公认的本地语言正在“扩展”一个接口)。
答案 2 :(得分:1)
您的问题源于您的_customerService
变量为ICustomerService
类型的事实。您的界面对抽象类一无所知。如果您希望该类型的东西具有特定的方法,则需要将其添加到您的界面中:
public interface ICustomerService
{
void DoOtherStuff();
string GetName();
}
然后,我将使您的抽象类实现成为接口,而不是您的CustomerService
类。您还需要在抽象类中添加一个abstract
方法,以便强制继承自抽象CustomerServiceBase
的所有类添加一个DoOtherStuff()
实现(您的抽象类不必添加自己的实现):
public abstract class CustomerServiceBase : ICustomerService
{
//abstract forces any inheriting class to implement 'DoOtherStuff' there
public abstract void DoOtherStuff();
//You could mark this as virtual if you want the option to override functionality
public string GetName()
{
return "John Doe";
}
}
CustomerService
应该是:
public class CustomerService : CustomerServiceBase
一旦这样做,您的Index()
方法就可以了:
public ActionResult Index()
{
//DoOtherStuff() and GetName() are both part of the interface now
_customerService.DoOtherStuff();
var name = _customerService.GetName();
return View();
}
答案 3 :(得分:0)
在CustomerService
方法中使用ICustomerService
代替Go
。
CustomerService _customerService = new CustomerService();
_customerService.DoOtherStuff();
var name = _customerService.GetName(); // Compiles now
答案 4 :(得分:0)
您进行ICustomerService _customerService
时
您正在启动ICustomerService合同,并且该合同没有名为GetName()
因此,您可以通过放置GetName()
获得合同,或者如上所述创建CustomerService
本身。
另外,抽象类的整体思想是交互,因此,基本上,当您将CustomerService
定义为非抽象类时,可以很好地使用
CustomerService customerService = new CustomerService
但是,CustomerService
或PhoneService
并不是TextService
更好的命名方式,因为这些是客户在现实生活中将直接与之交互的东西。并且使用CustomerService
本身而不是CustomerServiceBase
,因为人们将直接使用客户服务,但不会以上述电话或短信或其他服务的形式使用客户服务。
public abstract class CustomerService {} <-- Think in real life this doesnt have interaction
public class PhoneService() {} <-- This interacts directly