是否有可能在C#中有一个类实现一个接口,该接口声明了10个方法,但只实现了5个方法,即只定义了该接口的5个方法???实际上我有一个由3类实现的接口,并不是所有类都使用所有方法,所以如果我可以排除任何方法???
我需要这个。这可能听起来像一个糟糕的设计,但它没有希望。 问题是我有一组用户控件需要具有公共属性,并且只有我在运行时才显示它们。因为它是动态的我需要管理它们,因为我有属性。有些属性是少数类所需而不是所有属性。随着控件的增加,这个属性可能会增加,因此需要一个控件,我需要完全没有任何用处。只是虚拟方法。同样我认为如果有一种方法可以避免在其他类中使用这些方法,那就太棒了。听起来除了抽象类或虚函数之外别无他法: - (
答案 0 :(得分:25)
您可以将其设为抽象类,并将您不想实现的方法添加为抽象方法。
换句话说:
public interface IMyInterface
{
void SomeMethod();
void SomeOtherMethod();
}
public abstract class MyClass : IMyInterface
{
// Really implementing this
public void SomeMethod()
{
// ...
}
// Derived class must implement this
public abstract void SomeOtherMethod();
}
如果这些类都需要具体而不是抽象,那么你必须从方法中抛出NotImplementedException
/ NotSupportedException
。但更好的想法是分割界面,以便实现类不必这样做。
请记住,类可以实现多个接口,因此如果某些类具有某些功能但不是全部,那么您希望拥有更精细的接口:
public interface IFoo
{
void FooMethod();
}
public interface IBar()
{
void BarMethod();
}
public class SmallClass : IFoo
{
public void FooMethod() { ... }
}
public class BigClass : IFoo, IBar
{
public void FooMethod() { ... }
public void BarMethod() { ... }
}
这可能是你真正应该拥有的设计。
答案 1 :(得分:18)
您打破了界面的使用。对于每个常见行为,您应该具有单独的界面。
答案 2 :(得分:4)
这是不可能的。但是你可以做的就是抛出NotSupportedException
或NotImplementedException
来获取你不想实现的方法。或者您可以使用抽象类而不是接口。这样,您可以为您选择不覆盖的方法提供默认实现。
public interface IMyInterface
{
void Foo();
void Bar();
}
public class MyClass : IMyInterface
{
public void Foo()
{
Console.WriteLine("Foo");
}
public void Bar()
{
throw new NotSupportedException();
}
}
或者...
public abstract class MyBaseClass
{
public virtual void Foo()
{
Console.WriteLine("MyBaseClass.Foo");
}
public virtual void Bar()
{
throw new NotImplementedException();
}
}
public class MyClass : MyBaseClass
{
public override void Foo()
{
Console.WriteLine("MyClass.Foo");
}
}
答案 3 :(得分:4)
虽然我同意@PoweRoy,但您可能需要将界面分成更小的部分,您可以使用显式接口为您的界面实现提供更清晰的公共API。
例如:
public interface IPet
{
void Scratch();
void Bark();
void Meow();
}
public class Cat : IPet
{
public void Scratch()
{
Console.WriteLine("Wreck furniture!");
}
public void Meow()
{
Console.WriteLine("Mew mew mew!");
}
void IPet.Bark()
{
throw NotSupportedException("Cats don't bark!");
}
}
public class Dog : IPet
{
public void Scratch()
{
Console.WriteLine("Wreck furniture!");
}
void IPet.Meow()
{
throw new NotSupportedException("Dogs don't meow!");
}
public void Bark()
{
Console.WriteLine("Woof! Woof!");
}
}
使用上面定义的类:
var cat = new Cat();
cat.Scrach();
cat.Meow();
cat.Bark(); // Does not compile
var dog = new Dog();
dog.Scratch();
dog.Bark();
dog.Meow(); // Does not compile.
IPet pet = new Dog();
pet.Scratch();
pet.Bark();
pet.Meow(); // Compiles but throws a NotSupportedException at runtime.
// Note that the following also compiles but will
// throw NotSupportedException at runtime.
((IPet)cat).Bark();
((IPet)dog).Meow();
答案 4 :(得分:3)
您可以简单地使用您不想实现的方法抛出'NotImplementedException'。这样你仍然可以正常实现界面。
答案 5 :(得分:1)
不,不是。您必须定义接口的所有方法,但是您可以将它们定义为抽象,并将实现留给任何派生类。你不能编译一个表示实现接口的类,而实际上却没有。
答案 6 :(得分:1)
这是一个简单的愚蠢的例子,说明了不同用途的不同界面。公共属性没有接口,因为它会使示例复杂化。此代码还缺少许多其他好东西(如挂起布局),以使其更清晰。我没有尝试编译这段代码,所以可能会有很多错别字,但我希望这个想法很明确。
interface IConfigurableVisibilityControl
{
//check box that controls whether current control is visible
CheckBox VisibleCheckBox {get;}
}
class MySuperDuperUserControl : UserControl, IConfigurableVisibilityControl
{
private readonly CheckBox _visibleCheckBox = new CheckBox();
public CheckBox VisibleCheckBox
{
get { return _visibleCheckBox; }
}
//other important stuff
}
//somewhere else
void BuildSomeUi(Form f, ICollection<UserControl> controls)
{
//Add "configuration" controls to special panel somewhere on the form
Panel configurationPanel = new Panel();
Panel mainPanel = new Panel();
//do some other lay out stuff
f.Add(configurationPanel);
f.Add(mainPanel);
foreach(UserControl c in controls)
{
//check whether control is configurable
IConfigurableOptionalControl configurableControl = c as IConfigurableVisibilityControl;
if(null != configurableControl)
{
CheckBox visibleConfigCB = configurableControl.VisibleCheckBox;
//do some other lay out stuff
configurationPanel.Add(visibleConfigCB);
}
//do some other lay out stuff
mainPanel.Add(c);
}
}
答案 7 :(得分:0)
让您的接口在抽象类中实现。抽象类将实现5个方法,并将剩余的方法保持为虚拟。那么你的所有3个类都应该从抽象类继承。这是您使用3个类的客户端代码,不必更改。
答案 8 :(得分:0)
我想动态地将控件添加到我的表单中,因为我有我的要求。我找到了here的代码。我根据需要编辑了它。所以我有一个具有公共属性的IService类。这是由用户控件实现的。这些在运行时显示在不同的项目中。嗯,我有不同的公共接口,具有项目用于显示控件的属性。例如,很少有控件需要一些额外的方法或特性来基于运行时的用户选择来实现上下文菜单。即项目中的值将作为属性传递给控件,并将显示。现在这个菜单只有一个控件,其余的都没有。所以我想如果有办法不在所有类而不是一个类中使用这些方法。但听起来我需要选择虚拟方法或抽象类。对于我来说,嗯虚拟方法比抽象类更优选: - (
答案 9 :(得分:0)
实施SOLID原则之一,即接口隔离原则&#34;其中接口被分解为多个接口。
答案 10 :(得分:0)
除了上面关于设计接口的优秀建议外,如果你真的需要实现某些方法,可以选择使用“扩展方法”。在界面之外移动需要实现的方法。创建另一个静态类,将其实现为静态方法,第一个参数为“this interfaceObject”。这类似于LINQ for IEnumerable接口中使用的扩展方法。
public static class myExtension {
public static void myMethod( this ImyInterface obj, ... ) { .. }
...
}