C# 非接口方法
我一直在阅读有关接口编程而非实现的书籍。我没有完全理解的一个领域是如何处理非接口方法。例如,接口IAnimal和实现它的Cat类。我的例子是C语言,但我认为它也应该适用于其他语言C# 非接口方法,c#,oop,interface,abstract-class,C#,Oop,Interface,Abstract Class,我一直在阅读有关接口编程而非实现的书籍。我没有完全理解的一个领域是如何处理非接口方法。例如,接口IAnimal和实现它的Cat类。我的例子是C语言,但我认为它也应该适用于其他语言 public interface IAnimal { void Eat(); } public class Cat : IAnimal { public Cat() public void Eat() { //Do something
public interface IAnimal
{
void Eat();
}
public class Cat : IAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Meow()
{
return "meow";
}
}
据我所知,我似乎应该尝试使用接口,而不是cat实现,例如
Main()
{
IAnimal cat = new Cat();
}
但这使我无法访问我的meow方法,因为它不是IAnimal接口的一部分。我是否应该创建另一个实现IAnimals的接口ICat,并让Cat实现它?这是否意味着所有方法都应该是来自接口或抽象类的实现?或者我在这里做错了什么
感谢您的帮助。如果您需要访问该方法,则需要进行显式转换 在这种情况下,对于其他可能实现它的类,让Meow()方法更通用会更有趣:
public interface IAnimal
{
void Eat();
void Speak();
}
public class Cat : IAnimal
{
public void Eat() { }
public string Speak()
{
return "meow";
}
}
public class Dog : IAnimal
{
public void Eat() { }
public string Speak()
{
return "au";
}
}
你要做的是,你要有另一个界面,代表说英语的动物,或者从IAnimal继承,或者将其添加为第二个界面。具有会说话的动物的类实现第二个接口
public interface IAnimal
{
void Eat();
}
public interface ISpeakingAnimal : IAnimal
{
string Speak();
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
string ISpeakingAnimal.Speak()
{
return Meow();
}
public string Meow()
{
return "meow";
}
}
使用继承的接口
public interface IAnimal
{
void Eat();
}
public interface ISpeakingAnimal : IAnimal
{
string Speak();
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
string ISpeakingAnimal.Speak()
{
return Meow();
}
public string Meow()
{
return "meow";
}
}
具有第二个装饰器接口
public interface IAnimal
{
void Eat();
}
public interface ISpeakable
{
string Speak();
}
public class Cat : IAnimal, ISpeakable
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
如果需要的方法不是Speak()
,而是Meow()
,则可以使用显式接口实现仅通过该接口公开Speak()
方法
public interface IAnimal
{
void Eat();
}
public interface ISpeakingAnimal : IAnimal
{
string Speak();
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
string ISpeakingAnimal.Speak()
{
return Meow();
}
public string Meow()
{
return "meow";
}
}
接口的要点是定义实现该接口的类的通用行为。您正确地注意到,对cat的定义如下:
IAnimal cat = new Cat();
使您无法访问不在IAnimal中的Cat类中的方法。那么,为什么鼓励它以这种方式实施呢
答案很简单:它使以后更改代码变得非常容易。例如,如果我们有一个实现IAnimal的Dog类,如下所示:
public class Dog : IAnimal
{
// some methods
}
Cat cat = new Cat();
然后,我们可以很容易地将Cat类替换为Dog类,而无需更改任何其他代码。换言之,我们可以取代:
IAnimal cat = new Cat();
与
无需更改整个程序中的任何其他代码(除了变量名)。这是因为根据IAnimal定义Cat和Dog会迫使它们只使用IAnimal中的方法,尽管它们在Cat和Dog中的实现方式可能不同
当然,如果您只想使用特定于猫或狗的东西,您必须显式地定义类,正如@Erick在他的回答中提到的,如下所示:
public class Dog : IAnimal
{
// some methods
}
Cat cat = new Cat();
通常,您应该尝试在接口中定义尽可能多的常见行为,仅在绝对必要时显式地强制转换到特定类,如Cat或Dog。这使您的代码更加通用和多变。我在这个主题上的两点是,您确实需要依赖抽象(即接口)而不是实现 顺便说一句,这不是太过分了吗?不需要为对象模型中的任何类定义接口。如果需要接受满足给定契约的某些对象,通常需要定义接口 例如,我不会定义
IAnimal
或ICat
接口。可能我会定义一个抽象类Animal
,而只定义一个具体类Cat
如果出于某种原因,我需要在某个API中接受可以吃东西的生物,我会定义如下接口:
public interface IFeedable
{
void Feed(Food food);
}
如果一个活着的人能说话:
除非没有动物独有的特性/属性/行为,否则我将保留这些接口
如果你需要在某个地方制作一个对话对象:
ITalkative talkative = some as ITalkative;
if(talkative != null)
{
talkative.Talk();
}
或者,如果需要向对象馈送:
IFeedable feedable = some as IFeedable;
if(feedable != null)
{
feedable.Feed(new Vegetable());
}
正如您所看到的,您并没有为所有内容定义接口,只是为需要在某些API中处理的内容定义接口,您不关心谁可以执行某些操作和/或拥有某些数据,但是您只关心对象可以分别执行或公开某些行为和数据。您能为接口添加一个更通用的方法吗?
string speak()
。?然后,无论哪个类实现它,都可以有自己的消息。对于根本不会说话的类fish呢?那么它可以返回一个空字符串。或者没有声音的指示器。或者会说话的动物可以实现ITalkingAnimal
。因此,从评论中可以看出,您主张在相关接口中包含所有方法,而不是像示例中那样保留任何方法。对于何时实现多个接口与链接接口?取决于您计划如何使用它。作为你问题中的例子,你可以使用interitance。如果你有像IEnumerable makethespeak(IEnumerable obj)
这样的代码,你可能会使用ISpeakable
,所以如果你有可以说话但动物不能使用的东西(例如,你可能也有一个IRobot
),然后确认你是说所有的方法都应该在某个地方的接口上实现?你遵循一种模式,在某些地方它是有意义的,在某些地方它是没有意义的。例如,如果DTO对象具有属性,但没有方法,那么为其提供接口就没有意义。