简体   繁体   English

为什么我不能在我的实现中使抽象方法静态化?

[英]Why can't I make an abstract method static in my implementation?

Let's assume the following scenario in Java让我们假设以下 Java 场景

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
}

Why can I not make Baz.bar() static?为什么我不能将Baz.bar()静态?

Doing so results in the compiler error This static method cannot hide the instance method from Foo Adding an @Override annotation to Baz.bar() changes the compiler error to The method bar() of type Baz must override or implement a supertype method这样做导致编译器错误This static method cannot hide the instance method from Foo添加一个@Override注释Baz.bar()改变编译器错误到The method bar() of type Baz must override or implement a supertype method

It seems to me that from the perspective of anyone using the interface Foo , the implementing class Baz would still fulfill the interface requirements, while making a method that has a static implementation available to anyone who is explicitly using the Baz class without instantiation.在我看来,从使用接口Foo的任何人的角度来看,实现类Baz仍将满足接口要求,同时使具有静态实现的方法可供任何明确使用Baz类而无需实例化的人使用。

How come the compiler doesn't allow this scenario?为什么编译器不允许这种情况?

Edit :编辑

Maybe I wasn't clear enough, but what I'm actually asking is why this isn't allowed, since from my point of view, I'm not decreasing the visibility of the interface-defined method.也许我不够清楚,但我实际上要问的是为什么不允许这样做,因为从我的角度来看,我并没有降低接口定义方法的可见性。

And yes, I know I used the word abstract in the title, and not in the question, but that's because the abstract keyword is implied in an interface.是的,我知道我在标题中使用了抽象这个词,而不是在问题中,但那是因为abstract关键字隐含在接口中。

Edit 2 :编辑2

I'll add an example that is closer to reality for clarity on why I am even asking this:我将添加一个更接近现实的示例,以明确我为什么要问这个问题:

public interface DatabaseMapper<T extends DatabaseType> {
    Entry<T> convert(Entry);
}

public interface SQL extends DatabaseType {}

public class SQLEntry implements Entry<SQL> {}

public class SQLMapper implements DatabaseMapper<SQL> {
    public SQLEntry convert(Entry e) {
        //Convert some generic entry to the SQLEntry type
    }
}

In this case, I want to force all Mapper implementations to implement the convert method, but at the same time, this method might not depend in any way on the internal state of an SQLMapper object, and it might be desirable to be able to convert a generic Entry into a SQLEntry without going through an instantiation-process that probably includes database connection strings and the like.在这种情况下,我想强制所有Mapper实现实现convert方法,但同时,该方法可能不以任何方式依赖于SQLMapper对象的内部状态,并且可能希望能够转换一个通用的Entry SQLEntry Entry而不通过可能包括数据库连接字符串等的实例化过程。

This was the scenario I was faced with, and why I wanted to see if anyone knew why this was not possible to accomplish with the same method - eg not having to resort to a public static SQLEntry convertStatic(Entry e) which the overridden method delegates its implementation to.这就是我面临的场景,以及为什么我想看看是否有人知道为什么用相同的方法无法实现这一点 - 例如,不必求助于覆盖方法委托的public static SQLEntry convertStatic(Entry e)其实施。

Again though, I understand that this is not possible in Java due to how the compiler works - I am simply trying to understand why that is .不过,我再次明白,由于编译器的工作方式,这在 Java 中是不可能的——我只是想了解为什么会这样

The real answer is that Java simply wasn't defined this way. 真正的答案是,Java根本不是这样定义的。 In other language, this is possible. 换句话说,这是可能的。

For instance, in Scala there aren't static methods, but you can instead define static object that are singleton and that allow this. 例如,在Scala中没有静态方法,但是您可以改为定义单例的静态object并允许这种方法。 In dynamic language like Smalltalk or Ruby, classes are like objects, and this is also possible. 在像Smalltalk或Ruby这样的动态语言中,类就像对象,这也是可能的。

But in Java, static methods are similar to global methods. 但是在Java中,静态方法类似于全局方法。 There is not concept of self , nor super in a static method because it's not bound to an object. 静态方法中没有selfsuper概念,因为它没有绑定到对象。 By consequence inheritance/overriding doesn't really apply. 因此,继承/覆盖实际上并不适用。

It unfolds that if there is no notion of inheritance, it also doesn't make sense to speak of abstract . 它揭示了,如果没有继承的概念,那么abstract就没有意义。

Abstract methods are supposed to be overridden (Defined) by a subclass method. 假定抽象方法将被子类方法覆盖(定义)。 You can't override static methods as they do not pertain to an instance but to the specific class they are defined. 您不能覆盖静态方法,因为它们与实例无关,但与它们定义的特定类有关。

For example a non static method is used as such: 例如,使用非静态方法是这样的:

Foo b = new Baz();
Object result = b.bar();

static is used as such: 静态是这样使用的:

Object result = Baz.bar2();

if you really want bar to be static and also an override at the instance level do this: 如果您确实希望bar是静态的,并且还希望在实例级别进行覆盖,请执行以下操作:

public interface Foo {
    Object bar();
}

public class Baz implements Foo {
    @Override
    public Object bar() {
          return Baz.bar2();
    }
    public static Object bar2() {
     //your implementation
    }

}
public class Baz implements Foo {
    public Object bar() {
        //My implementation
    }
 public static  Object bar() {
        //My implementation
    }
}

because, your method signatures are same, bar () is not overloaded. 因为,您的方法签名相同,所以bar()不会重载。 as you have declared a non-static bar() in your abstract class, you are forced to implement that method in this class. 由于您在抽象类中声明了一个非静态的bar(),因此您不得不在此类中实现该方法。

int a = 2表示在后台内存中为“ a”和int类型分配内存,并在每次需要值时由2初始化,我只使用“ a”。以类似的方式,在加载类时初始化静态变量和方法,以便在任何类我都不需要使用new运算符来为静态变量分配内存,因为已经为它们分配了内存,因此它与对象无关,而抽象意味着它需要对象才能实现,因此两者都是矛盾的

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

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