java 如何声明抽象方法,以便参数类型(类)始终是 Children 类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6512202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:09:53  来源:igfitidea点击:

How do you declare an abstract method so that the parameter type (class) is always the Children class?

javainheritancemethodsabstract-class

提问by dominicbri7

EDIT : see bottom

编辑:见底部

First off I searched for an answer before asking this one, but as you can see with the title I have no idea how this is called and I will edit the question whenever I can. Please forgive me on this.

首先,我在问这个问题之前搜索了一个答案,但正如你在标题中看到的那样,我不知道这是怎么称呼的,我会尽可能编辑这个问题。请原谅我。

I have the following abstract class :

我有以下抽象类:

public abstract class ValidableDTO implements Serializable {
    public abstract boolean isValid();
    public abstract boolean equals(ValidableDTO compared);
    // EDIT : new solution
    public abstract <T extends ValidableDTO> boolean equals(T compared);
}

I'd like to get a similar implementation :

我想得到一个类似的实现:

public class MyDTO extends ValidableDTO {

    private String myValue; //With a getter and setter of course

    public MyDTO() {
        // ...
    }

    @Override
    public boolean isValid() {
        return true; // Validation
    }

// __________ LOOK AT THE FOLLOWING PARAMETER TYPE __________--
    @Override
    public boolean equals(MyDTO compared) {
        return true; // Comparison
    }
}

The closest I could get is

我能得到的最接近的是

@Override
public boolean equals(ValidableDTO compared) {
    boolean isEqual = false;

    if (compared instanceof MyDTO) {
        isEqual = getValue().equals(compared.getValue());
    }

    return isEqual;
}

I tried using public abstract boolean equals(<? extends ValidableDTO> compared);but this doesn't work.

我尝试使用,public abstract boolean equals(<? extends ValidableDTO> compared);但这不起作用。

Is that even possible(it shouldbe IMO) ? Thank you for your time and ... I still don't know how to describe this in 1 sentence... (lol)

这甚至可能吗(应该是 IMO)?谢谢你的时间和......我仍然不知道如何用1句话来描述这个......(笑)

Sincerely. - me

真挚地。- 我

One step closer, thanks to user : aps !

更近了一步,感谢用户:aps!

the following works in the Abstract class definition (ValidableDTO)

以下工作在抽象类定义(ValidableDTO)

public abstract <T extends ValidableDTO> boolean equals(T compared);

__BUT__

__但是__

the implementation in MyDTO still isn't fine and in the end, it's exactly the same as using my 'if instanceof' solution because ValidableDTO is an abstract class and HAS to be inherited.

MyDTO 中的实现仍然不好,最后,它与使用我的“if instanceof”解决方案完全相同,因为 ValidableDTO 是一个抽象类并且必须被继承。

What it looks like for now using Aps' solution :

现在使用 Aps 的解决方案的样子:

public <T extends ValidableDTO> boolean equals(T compared) { ... }

I still have to check if it's a MyDTO instance...

我仍然需要检查它是否是一个 MyDTO 实例......

ON A SIDE NOTE, google doesn't seem to know if "Validable" or "Validatable" are real words.. which one is correct?

附带说明一下,谷歌似乎不知道“Validable”或“Validatable”是否是真实的词..哪个是正确的?

回答by maasg

You can achieve that using generics on the declaration of your method signature at the abstract class:

您可以在抽象类的方法签名声明中使用泛型来实现这一点:

public abstract class ValidableDTO<T extends ValidableDTO> implements Serializable {
    public abstract boolean isValid();
    public abstract boolean equals(T compared);
}

public class MyDTO extends ValidableDTO<MyDTO> {

    @Override
    public boolean isValid() {
        ...
    }


    @Override
    public boolean equals(MyDTO compared) {
        return true; // Comparison
    }
}

[EDIT]

[编辑]

Summary of the comments discussion below:

以下评论讨论摘要:

Regarding Java coding style and principles, it would be more reasonable to override the default public boolean equals(Object other)method instead of using a generics construction to try to constrain the type of the parameter. The standard practice for equals(...) is to use the instaceof operator to check for parameter compatibility, perform a cast and use finer-grained comparisons at the level of the specific object structure. That's similar to the proposed alternative implementation in the original post.

关于 Java 编码风格和原则,覆盖默认public boolean equals(Object other)方法而不是使用泛型构造来尝试约束参数的类型会更合理。equals(...) 的标准做法是使用 instaceof 运算符检查参数兼容性、执行强制转换并在特定对象结构级别使用更细粒度的比较。这类似于原始帖子中提议的替代实现。

 @Override
public boolean equals(Object other) {
    if (this == other) return true;
    if (other instanceof MyDTO) { 
        MyDTO otherDTO = (MyDTO) other; 
        return this.getValue().equals(otherDTO.getValue()); // mind null values
    } 
    return false; 
}

This approach has the additional value of making the class ready for use in a collection, which is a very common case for DTO classes (e.g. List<UserDTO>)

这种方法具有使类准备好在集合中使用的附加价值,这是 DTO 类的一个非常常见的情况(例如List<UserDTO>