简体   繁体   English

具有空方法的 class 与抽象 class?

[英]A class with empty methods vs abstract class?

Why can't we have a normal class with empty methods in it, and then sub-classes which override the base-class' empty methods, instead of an abstract class?为什么我们不能有一个带有空方法的普通 class,然后是覆盖基类的空方法的子类,而不是抽象的 class? For example:例如:

class Base {
    
    void methodA() {
        //empty
    }
    
    void methodB() {
        //empty
    }
}
    
class Sub extends Base {

    void methodA() {
        //implementation
    }
    
    void methodB() {
        //implementation
    }
}

I assume that what you really ask is "Why do we need abstract classes/methods, when we can just have a normal class with empty methods instead".我假设您真正要问的是“为什么我们需要抽象类/方法,而我们可以只使用带有空方法的普通 class ”。

And the answer to that question is that with the abstract method, the sub class MUST provide an implementation.这个问题的答案是使用抽象方法,子 class 必须提供一个实现。 If the method is not in parent is not abstract, then nothing requires the sub to provide an implementation at all.如果方法不在 parent 中,则不是抽象的,则根本不需要 sub 提供实现。

This is important in cases where an empty implementation of a method makes no sense, because then the compiler can give you an error, because your sub class have not implemented all required methods.这在方法的空实现没有意义的情况下很重要,因为编译器可能会给您一个错误,因为您的子 class 没有实现所有必需的方法。

In your specific case, where you have 2 methods which don't return anything, it may be alright to do what you're doing.在您的特定情况下,如果您有 2 个不返回任何内容的方法,则可以执行您正在执行的操作。 It's kind of flirting on the edges of the null object pattern , but not quite.这是在null object 模式的边缘调情,但不完全是。 There's nothing stopping you from doing it that way;没有什么能阻止你这样做; it will compile.它会编译。 In some designs, it may even be a good choice.在某些设计中,它甚至可能是一个不错的选择。 Your example is too contrived to say whether or not it's a good idea.你的例子太做作了,不能说这是否是一个好主意。

Suppose you have a method which returns a value, though.不过,假设您有一个返回值的方法。 You can't just put a comment //do nothing because you need a return to satisfy the compiler.你不能只是发表评论//do nothing因为你需要一个返回来满足编译器。 So you add a sentinel value.所以你添加了一个哨兵值。 This is pretty error prone, as it relies on callers being aware of the values which have special meanings.这很容易出错,因为它依赖于调用者意识到具有特殊含义的值。 It may even be the case that no suitable sentinel value even exists, if the set of genuine results contains every possible value.如果一组真实结果包含所有可能的值,甚至可能不存在合适的标记值。

class Base {
    void methodA() {
        //empty
    }
    
    int getFoo() {
        // Don't do this, just an example
        return -1;
    }
}

Someone might instantiate new Base() and not realise that their code is destined to be useless, and that the class's author intended for them to instantiate Sub or another child class.有人可能会实例化new Base()而没有意识到他们的代码注定是无用的,并且该类的作者打算让他们实例化Sub或另一个子 class。 They might not know they're supposed to check sentinel values, etc.他们可能不知道他们应该检查哨兵值等。

It would be better in this case if they couldn't do that.如果他们不能这样做,在这种情况下会更好。 It would be better to mark Base as an incomplete implementation, and tell the compiler that it must be completed to be any use.最好将Base标记为不完整的实现,并告诉编译器它必须完成才能使用。 This is precisely what abstract classes are for.这正是抽象类的用途。

By marking a class as abstract, you are telling the compiler that users are not allowed to instantiate this class because, for whatever reason, doing so does not make sense.通过将 class 标记为抽象,您告诉编译器不允许用户实例化此 class,因为无论出于何种原因,这样做没有意义。

By marking a method as abstract, you are telling the compiler that a child class must provide an implementation in order to itself be instantiable (the child class could also be abstract, kicking the can down the road to child class of itself to provide an implementation).通过将方法标记为抽象,您是在告诉编译器子 class 必须提供实现才能使其自身可实例化(子 class 也可以是抽象的,将罐子踢到子 ZA2F2ED4F8EBC2CBB4C21A29DC40 的实现上)。

abstract class Base {
    void methodA() {
        //empty
    }
    
    abstract int getFoo();
}

TL;DR your one specific example does not prove that abstract classes have no utility. TL; DR 你的一个具体例子并不能证明抽象类没有用处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM