Java 中使用泛型返回类型重写方法

发布于 2024-12-06 20:57:28 字数 584 浏览 1 评论 0原文

在返回类型中使用泛型时,我在扩展父类时遇到问题 就像下面的例子一样。

如您所知,如果没有泛型,下面的示例将正常编译,但它不会是类型安全的,因为它的类型应该是 Object。

有什么明确的解决方案(或模式,或建议,任何东西都会有帮助!)我可以参考吗?

class AbstractReader<T>{
    public abstract T readNext();
}
class ByteArrayReader extends AbstractReader<byte[]>{
    @Override
    public byte[] readNext(){   /*...*/ }
}
class StringReader extends ByteArrayReader {
    @Override
    public String readNext() {  
        /* The return type is incompatible 
           with ByteArrayReader.readNext()! */
        return new String(bytes);
    }
}

When using generics in the return type, I'm having trouble extending a parent class
like following example.

As you know, without generics, the following example will be compiled normally, but it won't be type safe because it's type should be Object.

Is there any clear solution (or pattern, or advice, anything will be helpful!) that I can refer to?

class AbstractReader<T>{
    public abstract T readNext();
}
class ByteArrayReader extends AbstractReader<byte[]>{
    @Override
    public byte[] readNext(){   /*...*/ }
}
class StringReader extends ByteArrayReader {
    @Override
    public String readNext() {  
        /* The return type is incompatible 
           with ByteArrayReader.readNext()! */
        return new String(bytes);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

提笔书几行 2024-12-13 20:57:29

您可以使用装饰器设计模式而不是继承:

class StringReader {
    private ByteArrayReader bar;

    public StringReader(ByteArrayReader bar) {
        this.bar = bar
    }

    public String readNext() {
        return new String(this.bar.readNext());
    }
}

You could use the Decorator Design Pattern instead of inheritance:

class StringReader {
    private ByteArrayReader bar;

    public StringReader(ByteArrayReader bar) {
        this.bar = bar
    }

    public String readNext() {
        return new String(this.bar.readNext());
    }
}
简美 2024-12-13 20:57:29

您的问题试图告诉您的是,这不是继承的良好用途。 StringReader 与 ByteArrayReader 绝对没有 is-a 关系。如果它们之间有一些共同的功能,那只是一个实现细节。任何此类通用代码都应该被推送到 AbstractReader,两者都应该直接扩展。然后,抽象类正确地包含其子类共有的代码,并且 StringReader 和 ByteArrayReader 除了是同一事物(大概是 Reader)的实现之外,正确地不相关。

What your problems are trying to tell you is that this isn't a good use of inheritance. A StringReader definitely doesn't have an is-a relationship to a ByteArrayReader. If there's some functionality in common between them, that's merely an implementation detail. Any such common code should be pushed up to AbstractReader from which both should extend directly. Then the abstract class correctly contains code common to its subclasses and StringReader and ByteArrayReader are correctly unrelated besides being implementations of the same thing (presumably a Reader).

晨与橙与城 2024-12-13 20:57:28

这里的问题是 StringReader 扩展 ByteArrayReader 没有意义。您将继承与组合混淆了。

StringReader 继承自 ByteArrayReader 时,您是说它将履行一个约定,该约定表示它有一个 readNext 方法,该方法返回一个 byte[ ]

您真正想做的是使用组合而不是继承:

class StringReader extends AbstractReader<String> {
    private AbstractReader<byte[]> downstream;

    public StringReader(AbstractReader<byte[]> downstream) {
        this.downstream = downstream;
    }

    public String readNext() {
        return new String(downstream.readNext());
    }
}

此 StringReader 满足 AbstractReader 契约,并按照以下方式实现下游 AbstractReader。请注意,它没有明确要求 ByteArrayReader - 任何旧的 AbstractReader 都可以工作。

The problem here is that there it doesn't make sense for StringReader to extend ByteArrayReader. You have confused inheritance with composition.

When StringReader inherits from ByteArrayReader you are saying that it will fulfill a contract that says it has a readNext method that returns a byte[].

What you really want to do is use composition rather than inheritance:

class StringReader extends AbstractReader<String> {
    private AbstractReader<byte[]> downstream;

    public StringReader(AbstractReader<byte[]> downstream) {
        this.downstream = downstream;
    }

    public String readNext() {
        return new String(downstream.readNext());
    }
}

This StringReader fulfills the AbstractReader<String> contract, and is implemented in terms of a downstream AbstractReader<byte[]>. Note that it does not explicitly require a ByteArrayReader - any old AbstractReader<byte[]> will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文