是否有Java或C#中的构造强制继承类来调用基础实现?你可以调用super()或base()但是如果没有调用它可能会抛出编译时错误吗?那会很方便..
- 编辑 -
我对覆盖方法感到好奇。
答案 0 :(得分:15)
没有也不应该做任何事情。
如果在基类中有这样的东西,我可以想到最接近的事情:
public virtual void BeforeFoo(){}
public void Foo()
{
this.BeforeFoo();
//do some stuff
this.AfterFoo();
}
public virtual void AfterFoo(){}
并允许继承类覆盖BeforeFoo和/或AfterFoo
答案 1 :(得分:7)
不是Java。它可能在C#中,但其他人将不得不与之对话。
如果我理解正确你想要这个:
class A {
public void foo() {
// Do superclass stuff
}
}
class B extends A {
public void foo() {
super.foo();
// Do subclass stuff
}
}
你可以用Java来强制使用超类foo,如下所示:
class A {
public final void foo() {
// Do stuff
...
// Then delegate to subclass
fooImpl();
}
protected abstract void fooImpl();
}
class B extends A {
protected void fooImpl() {
// Do subclass stuff
}
}
它很难看,但它可以达到你想要的效果。否则你只需要小心确保调用超类方法。
也许你可以修补你的设计来解决问题,而不是使用技术解决方案。这可能是不可能的,但可能值得考虑。
编辑:也许我误解了这个问题。你是在谈论一般的构造函数或方法吗?我总体上假设了方法。答案 2 :(得分:4)
您可能需要查看此内容(调用super antipatern)http://en.wikipedia.org/wiki/Call_super
答案 3 :(得分:2)
如果我理解正确你想要强制你的基类行为没有被覆盖,但仍然能够扩展它,那么我将使用模板方法设计模式,而在C#中不包括虚拟关键字方法定义。
答案 4 :(得分:2)
以下示例在覆盖方法时未继承基本功能时抛出InvalidOperationException
。
这可能对某些内部API调用该方法的情况很有用。
即。其中Foo()
未设计为直接调用的地方:
public abstract class ExampleBase {
private bool _baseInvoked;
internal protected virtual void Foo() {
_baseInvoked = true;
// IMPORTANT: This must always be executed!
}
internal void InvokeFoo() {
Foo();
if (!_baseInvoked)
throw new InvalidOperationException("Custom classes must invoke `base.Foo()` when method is overridden.");
}
}
<强>使用:强>
public class ExampleA : ExampleBase {
protected override void Foo() {
base.Foo();
}
}
<强>叫喊:强>
public class ExampleB : ExampleBase {
protected override void Foo() {
}
}
答案 5 :(得分:1)
没有。这不可能。如果你必须有一个执行某些前置或后置操作的函数,请执行以下操作:
internal class Class1
{
internal virtual void SomeFunc()
{
// no guarantee this code will run
}
internal void MakeSureICanDoSomething()
{
// do pre stuff I have to do
ThisCodeMayNotRun();
// do post stuff I have to do
}
internal virtual void ThisCodeMayNotRun()
{
// this code may or may not run depending on
// the derived class
}
}
答案 6 :(得分:1)
我没有在这里阅读所有回复;但是,我正在考虑同样的问题。在回顾了我真正想要做的事情之后,在我看来,如果我想强制调用基本方法,我不应该首先声明基本方法虚拟(覆盖能力)。
答案 7 :(得分:0)
不要认为内置任何可行的解决方案。我确信有单独的代码分析工具可以做到这一点。
答案 8 :(得分:0)
编辑误读构造作为构造函数。因为它适合问题的一个非常有限的子集,所以继续作为CW。
在C#中,您可以通过定义在基本类型中至少有一个参数的单个构造函数来强制执行此行为。这将删除默认构造函数并强制派生类型explcitly调用指定的基数,否则会出现编译错误。
class Parent {
protected Parent(int id) {
}
}
class Child : Parent {
// Does not compile
public Child() {}
// Also does not compile
public Child(int id) { }
// Compiles
public Child() :base(42) {}
}
答案 9 :(得分:0)
在java中,编译器只能在Constructors的情况下强制执行此操作。
必须在继承链中一直调用构造函数。即如果Dog扩展Animal extends Thing,Dog的构造函数必须调用Animal的构造函数,必须为Thing调用构造函数。
常规方法不是这种情况,程序员必须在必要时显式调用超级实现。
强制执行某些基本实现代码的唯一方法是将可覆盖的代码拆分为单独的方法调用:
public class Super
{
public final void doIt()
{
// cannot be overridden
doItSub();
}
protected void doItSub()
{
// override this
}
}
public class Sub extends Super
{
protected void doItSub()
{
// override logic
}
}
答案 10 :(得分:0)
我偶然发现了这个帖子,并不一定喜欢任何特定的答案,所以我想我会提供自己的...
C#中没有办法强制调用基本方法。因此,编码被认为是反模式,因为后续开发人员可能没有意识到他们必须调用基本方法,否则该类将处于不完整或不良状态。
但是,我发现需要此类功能并且可以相应地实现的情况。通常,派生类需要基类的资源。为了获得通常可能通过属性公开的资源,它通过方法公开。派生类别无选择,只能调用该方法来获取资源,从而确保执行基类方法。
可能会问的下一个逻辑问题是为什么不把它放在构造函数中呢?原因是它可能是一个操作顺序问题。在构建类时,可能仍有一些输入缺失。
这是否远离了这个问题?是的,不是。是的,它确实强制派生类调用特定的基类方法。不,它不会使用override关键字执行此操作。这可能对寻找这篇文章答案的个人有所帮助。
我不是在宣传这个福音,如果个人看到这种方法的缺点,我很乐意听到它。
答案 11 :(得分:0)
不要强制进行基本呼叫。使父方法执行您想要的操作,同时在其主体中调用可覆盖(例如:抽象)的受保护方法。
答案 12 :(得分:0)
我使用以下技术。请注意,Hello()
方法是受保护的,因此不能从外部调用它。
public abstract class Animal
{
protected abstract void Hello();
public void SayHello()
{
//Do some mandatory thing
Console.WriteLine("something mandatory");
Hello();
Console.WriteLine();
}
}
public class Dog : Animal
{
protected override void Hello()
{
Console.WriteLine("woof");
}
}
public class Cat : Animal
{
protected override void Hello()
{
Console.WriteLine("meow");
}
}
用法示例:
static void Main(string[] args)
{
var animals = new List<Animal>()
{
new Cat(),
new Dog(),
new Dog(),
new Dog()
};
animals.ForEach(animal => animal.SayHello());
Console.ReadKey();
}
哪个会产生: