Это сторона проблемы ковариации. См. Например, Covariance and contravariance. И Demonstrate covariance and contravariance in Java?. На самом деле Java не отличается, но есть несколько вариантов.
Во-первых, при переопределении метода вы можете объявить более конкретный тип возвращаемого значения. Например, в MySubClass
вы можете объявить:
@Override
public MySubClass filterOn(String something) {
// ...
}
Теперь это не решает проблему. Вам все еще нужен способ для этого метода создать и сделать что-то для объекта MySubClass
. Что он делает, он освобождает код клиента от необходимости приведения вообще. Вы можете взять реализацию ответа метода отправки формы davidxxx (при условии, что result.doSomethingUsingThisInstance()
является protected
или public
):
@Override
public MySubClass filterOn(String something) {
MySubClass result = new MySubClass();
result.doSomethingUsingThisInstance(this, something);
return result;
}
Вы можете быть раздражены, чтобы дублировать этот метод во всех вас подклассах. Если реальная работа остается в result.doSomethingUsingThisInstance()
, я думаю, вы сможете жить с ней.
Другая идея состоит в том, чтобы clone()
для создания объекта нужного типа исполнения:
public class MyClass implements Cloneable {
public MyClass filterOn(String something) {
try {
MyClass result = (MyClass) this.clone();
result.doSomethingUsingThisInstance(this, something);
return result;
} catch (CloneNotSupportedException cnse) {
throw new AssertionError(cnse);
}
}
}
Я бы дважды подумать, прежде чем использовать эту идею, хотя. Одна из причин, по которой ваш клон содержит данные, которые вы не хотите находиться там, поэтому вам, возможно, придется убедиться, что он очищен до работы с клоном. Вы все еще можете объединить его с возвращением конкретный подтип в подклассе, теперь он просто требует приведение (все еще в реализации, ничего клиент не должен беспокоиться о):
public class MySubClass extends MyClass {
@Override
public MySubClass filterOn(String something) {
return (MySubClass) super.filterOn(something);
}
}
Возвращаемое значение 'filterOn' является' MyClass', а не 'MySubClass', поэтому исключение действительно достаточно. Измените тип 'result', чтобы исправить его. – Henrik
'MyClass result = new MyClass();' в вашем методе фильтра есть проблема. вы создаете супер-экземпляр и возвращаетесь в конце, вы не можете использовать его в подтипе. Возможно, вы захотите переопределить метод filterOn в MySubClass. – Kent
Простейшим решением было бы не использовать 'subClass2', поскольку это не« MySubClass ». Если вам нужен экземпляр 'MySubClass', чем просто перезаписать' filteron' и вернуть экземпляр 'MySubClass' вместо – n247s