我在JAVA中实现了两个读者。见下文:
public final class ReaderA {
public ReaderA() {}
public static int read(final File file) {
final byte[] data = Files.readAllbytes(file.toPath());
return read(data);
}
public static int read(final byte[] data) {
// do somethingA
}
...// and some other methods
}
public final class ReaderB {
public ReaderB() {}
// this method is exactly the same as in ReaderA
public static int read(final File file) {
final byte[] data = Files.readAllbytes(file.toPath());
return read(data);
}
// this is implemented different from the one in ReaderA
public static int read(final byte[] data) {
// do somethingB
}
...// and the same other methods as in ReaderA
}
问题。避免重复代码的最佳方法是什么?
我尝试在新的抽象类Reader
中提取重复的代码,并尝试制作read(final byte[] data)
摘要并在子类ReaderA
和ReaderB
中实现它。它不起作用,因为这些方法是静态的。
答案 0 :(得分:2)
除非您从static
中删除read(byte[])
修饰符并创建实例,否则您将无法使用继承来帮助您。
static
方法的行为与实例方法不同,无法覆盖。相反,超类和子类都将具有需要使用类名限定的单独方法。拉起read(File)
意味着它总是调用超类的read(byte[])
。您仍然需要将read(File)
复制到每个子类,以使其使用该类自己的read(byte[])
。 Ward's answer中的代码也显示了这一点。
供参考,请阅读此问题及其答案:Are static methods inherited in Java?
举例说明:您拥有的两种read(File)
方法不"完全相同"就像你在你的代码片段中所说的那样。他们不会同时拨打this.read(data)
,而是拨打ReaderA.read(data)
和ReaderB.read(data)
。了解read(byte[])
调用如何处理两种完全不同的,不可覆盖的方法。
如果它在您的权力范围内,我建议以不太静态的方式重写读者:
interface Reader
{
default int read(File file)
{
final byte[] data = Files.readAllbytes(file.toPath());
return read(data);
}
int read(byte[] data);
}
class ReaderA
implements Reader
{
int read(byte[] data)
{
// do somethingA
}
}
class ReaderB
implements Reader
{
int read(byte[] data)
{
// do somethingB
}
}
注意read(File)
现在对于所有实现类是如何相同的。当然,您必须更改从ReaderX.read()
到new ReaderX().read()
调用方法的方式。
答案 1 :(得分:1)
我认为你需要首先问自己几个问题:
我认为您应该阅读SOLID原则,特别是开放/封闭原则和依赖性反转
答案 2 :(得分:0)
如果您正在使用Java SE 8,则可以将静态方法放在界面中。 Java接口静态方法类似于默认方法,除了我们不能在实现类中覆盖它们。此功能有助于我们避免在实现类中实现不良而导致意外结果。
答案 3 :(得分:0)
有一些可能性:
我建议不要这样做:你可能会在你的子类中获得其他方法,你可能不想这样做。
将它提取到两个类的公共超类
从另一个类中调用该方法。如果两者保持相同的功能,这将起作用
答案 4 :(得分:0)
我不确定使用静态方法保持此实现是最好的,但如果是这样,您可以添加Function
参数。
public class Reader {
public static int read(final File file, Function<byte[], Integer> reader) {
final byte[] data = Files.readAllbytes(file.toPath());
return reader.apply(data);
}
}
然后像这样使用它:
public final class ReaderA {
public static int read(final File file) {
return Reader.read(file, ReaderA::read);
}
public static int read(final byte[] data) {
// do somethingA
}
}
自Java 8中引入functional interfaces和method references以来,几乎没有任何重复的代码部分无法避免。