Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:抽象类中的静态方法调用抽象非静态方法?_Java_Methods_Static_Instance - Fatal编程技术网

Java:抽象类中的静态方法调用抽象非静态方法?

Java:抽象类中的静态方法调用抽象非静态方法?,java,methods,static,instance,Java,Methods,Static,Instance,我有一个抽象类A 我有大约10门课,可以延长一个学期 类A有一个或两个静态方法,它们是静态的,这是有意义的,因为它们属于10个类,而不是它们的实例。例如,一个静态方法叫做getAllFromX,它从X获取类的所有实例,不管是什么,它可能是一个服务器,实际上是,但这并不重要。因此,您可以看到,这些方法是静态的,并且不绑定到实例 同时类A有一个非静态的抽象方法,每个子类重写这个方法(只返回一个字符串)。我不能使其成为静态的,因为静态方法不能被重写(…) 总结:抽象类A有一个静态方法和一个抽象的非静态

我有一个抽象类A

我有大约10门课,可以延长一个学期

类A有一个或两个静态方法,它们是静态的,这是有意义的,因为它们属于10个类,而不是它们的实例。例如,一个静态方法叫做getAllFromX,它从X获取类的所有实例,不管是什么,它可能是一个服务器,实际上是,但这并不重要。因此,您可以看到,这些方法是静态的,并且不绑定到实例

同时类A有一个非静态的抽象方法,每个子类重写这个方法(只返回一个字符串)。我不能使其成为静态的,因为静态方法不能被重写(…)

总结:抽象类A有一个静态方法和一个抽象的非静态方法,由子类重写。我不能使第二个方法成为静态的,因为它必须被重写。另一方面,我可以使第一个方法成为非静态的,但这将是非常难看和糟糕的编程风格,所以我将保持这种方式

陷阱?类A中的静态方法必须获得非静态方法返回的值(当然,对于静态方法继承自的子类)

使用反射完成这项任务的“最简单”方法是什么?我是说…真的吗

例如,我得到静态方法所在的类:

Class<?> cl=new Object(){}.getClass().getEnclosingClass(); (a hack I found here, thank god...)
Class cl=new Object(){}.getClass().getEnclosingClass();(谢天谢地,我在这里找到了一个黑客…)
然后我使用getConstructor来构造这个子类的一个对象

然后我用这个对象调用非静态方法

真的吗??这样做难道不容易吗?我的意思是如果我想设计概念正确的程序


来自C#我不喜欢那样(还有类型擦除的事情)。真是难看。可行但丑陋。这是一个很大的绊脚石,至少对初学者来说是这样。编辑:再读一遍后,我会加上:/rant结束。抱歉,但我真的很在乎。

您可以始终使用反射来调用使用类名的方法,例如

    Object objectX = ClassX.class.newInstance();
    //get your method passing argument types as second param
    Method method = ClassX.class.getDeclaredMethod("methodX", null);
    //invoke your method passing arguments as second param
    method.invoke(objectX, null);
由于您提到静态方法不使用任何实例,但您使用的是反射来获取实例,因此我真的不确定它如何符合您的需求


我认为将其作为抽象类中的实现方法(非静态)是一个更好的选择。这样,您可以实现一次,但在所有10个扩展类中都可以使用。

我认为您实际上需要的是:

public class A {
    public static Set<A> getAllFromX() {
        ...
    }
}

public class B extends A {
    public static Set<B> getAllFromX() {
        ...
    }
}


public class C extends A {
    public static Set<C> getAllFromX() {
        ...
    }
}
编译器不会拒绝编译它,但会将其转换为

A.foo();

因此,在
foo()
中无法执行依赖于调用
foo()
的类的操作,因为它始终是一个类。

我认为您的问题在于更大的设计。另一个对象应该负责检索一个或其子类的实例。如您所见,依赖由子类替换的静态方法并不能很好地工作。如果不了解问题域,很难给出一个好的答案,但我会考虑类似于抽象工厂模式的东西。
广义地说:使用方法集合getInstances()定义一个抽象类AFactory。如果需要在重写的getInstances()方法中返回并实现该逻辑,请为的每个具体子类扩展AFactory。您还可以在抽象工厂getFactory(Class)上提供一个静态方法,以便在运行时获取适当的工厂子类型。

如果没有任何实例可以调用实例方法,那么从静态方法调用非静态方法是没有意义的。向我们解释你想用这些方法实现什么,我们可能会找到解决方案。你们都是对的@这是一个很好的Java设计,与C#一样。这就是为什么我希望非静态方法是静态的。但在Java中,我不能覆盖静态。这不是好的Java设计。在类级别上重写不仅实例级别必须是可能的。不能重写静态方法,因为它们不是继承的。如果您调用
subassofa.theStaticMethod()
,实际上您正在调用
A.theStaticMethod()
。编译器允许您这样调用它,但生成的字节码是:
A.theStaticMethod()
。如果您希望每个子类都有自己的静态方法,那么必须将其添加到每个子类中,然后将隐藏在A中定义的静态方法。好的,谢谢,我不知道这一点语法糖。
A.foo();