关于Java子类,继承返回"this"的方法的Java子类. [英] Regarding Java subclasses inheriting methods that return "this"

查看:227
本文介绍了关于Java子类,继承返回"this"的方法的Java子类.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

具有带有公共方法的类Car

Have a class Car with a public method

public Car myself() {
  return this;
}

具有子类Ferrari和包含Ferrari对象的变量foo.

Have a subclass Ferrari, and a variable foo that contains a Ferrari object.

最后,

Ferrari bar = foo.myself();

这会警告您,因为方法myself()返回的是Car对象,而不是预期的Ferrari.

This will warn you, because the method myself() returns a Car object, rather than the expected Ferrari.

注意:我知道该示例很愚蠢,因为您只需要执行bar = foo即可.这只是一个例子.

Note: I know that the example is stupid because you'd just do bar = foo. It's just an example.

解决方案:

  • 覆盖Ferrari中的myself()方法.
  • 分配bar时,将Car对象投射为Ferrari对象.
  • Override the myself() method in Ferrari.
  • Cast the Car object to a Ferrari object when assigning bar.

这两种解决方案都可以,我对此表示满意.但是,当您有几个Car的子类时,第一个是不希望的.我觉得一遍又一遍地覆盖方法会破坏继承它的意义.接下来,关于第二种解决方案,投射不是很漂亮.感觉很傻-如果我的变量的类型为Ferrari,Java是否应该能够在不警告我的情况下隐式转换它?毕竟,Java必须知道可以将返回的对象 强制转换为Ferrari,不是吗?

Both solutions work and I am okay with that. However, the first one is undesirable when you have several subclasses of Car. I feel that overriding a method over and over defeats the point of inheriting it. Next, regarding the second solution, casting is not pretty. It feels silly - if my variable is of type Ferrari, shouldn't Java be able to implicitly cast it without warning me? After all, Java must know that the returned object can be casted to Ferrari, no?

还有其他解决方法吗?出于好奇-我可以忍受铸造的东西,告诉Java应该是什么...

Is there another workaround? Just out of curiosity - I can live with casting stuff, telling Java what things are supposed to be...

推荐答案

此解决方案使用泛型的方式在Java库中更常见.

This solution uses generics in a way that is used more often in the Java libraries.

它有效,您不必每次都强制转换结果,也不必在每个子类中覆盖myself方法.

It works and you don't have to cast the result every time nor override the myself method in every subclass.

我相信这是唯一不需要覆盖或强制转换的解决方案.它确实要求每个子类使用其自己的类型作为超类Car:class Ferrari extends Car<Ferrari>

I believe that it is the only solution that doesn't require overriding or casting. It does require each subclass to use its own type as a type parameter to the superclass Car: class Ferrari extends Car<Ferrari>

class Car<X extends Car<X>> {
    public X myself() {
        return (X) this;
    }
}

class Ferrari extends Car<Ferrari> {
}

然后按预期使用它:

Ferrari testarossa = new Ferrari().myself();

这个概念在Java标准库中也以一种或多种方式多次使用:

This concept is used in the Java standard libraries a few times as well in one way or another:

java.lang.Enum

java.lang.Enum

public abstract class Enum<E extends Enum<E>>

java.util.Comparable

java.util.Comparable

public interface Comparable<T>

(实现可比对象时,您应该传递自己的类类型:class ShoeSize implements Comparable<ShoeSize>)

(You're supposed to pass your own class type when you implement a comparable: class ShoeSize implements Comparable<ShoeSize>)

方法链接

这也有很好的用途-有一种模式,某些人喜欢这种模式,它允许方法链接.这是StringBuilder的作用:new StringBuilder().append("a").append("b").toString().但是,支持方法链接的类通常很难子类化.使用上面概述的方法,可以在这种情况下进行子类化.

There's a good use for this too - there is a pattern, favored by some, that allows method chaining. This is what StringBuilder does: new StringBuilder().append("a").append("b").toString(). However a class that supports method chaining is often hard to subclass. Using the approach I outlined above makes it possible to subclass in this situation.

这篇关于关于Java子类,继承返回"this"的方法的Java子类.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆