У меня есть интерфейс Readable и класс ReadableImpl, который его реализует.
public interface Readable {
void doThis();
void doThat();
}
public class ReadableImpl implements Readable {
public void doThis() {
System.out.println("do this");
}
public void doThat() {
System.out.println("do that");
}
}
Что мне делать, если я хочу переопределить метод doThis()? Должен ли я реализовать Readable в другом классе?
Обновлено: я не хочу редактировать класс ReadableImpl
Вы реализовали doThis() в ReadableImpl. Если вы хотите переопределить метод, он должен быть в другом классе, расширяющем ReadableImpl. Если вы хотите переопределить в классе, вы должны правильно усвоить основы. Внутри класса есть overloading, у которого есть свои ограничения.
Вы уже переопределили (я бы сказал, реализовали), не так ли?
@Ran Должен ли я создать еще один класс public class ReadableImpl2 extends ReadableImpl implements Readable ?
В зависимости от того, что вы хотите сделать, вы можете счесть приемлемым перегрузкаdoThis в том же классе и, например, просто изменить сигнатуру метода для другого поведения.
@ user25963 да! нет необходимости заново реализовывать интерфейс Readable.
Ваш вопрос кажется очень неясным, поскольку он не говорит, где вы хотите переопределить метод. Если вы хотите просто реализовать один метод doThis(), вам нужно сделать этот класс абстрактным, а затем создать подкласс для этого, который будет реализовывать оставшиеся абстрактные методы. Согласно приведенному вами коду, поскольку Readable является интерфейсом, а ReadableImpl реализует Readable, следовательно, он уже переопределяет метод <или вы можете сказать реализацию>.




Ваш пример уже отменяет это!
Вы можете просто переопределить doThis() в классе ReadableImpl напрямую.
Пока вы реализуете интерфейс в своем классе, вы можете переопределить любой метод в интерфейсе, просто написав точно такое же имя метода / тип возвращаемого значения / параметр в этом классе.
Технически вы реализуете (некоторые называют это переопределением) в ReadableImpl. Если вы хотите переопределить снова, это должно быть в классе, который расширяет ReadableImpl, и не нужно повторно реализовывать Readable. Просто,
public class ReadableImpl2 extends ReadableImpl {
@override
public void doThis() {
System.out.println("do this overriden");
}
}
Я согласен с @Ran в отношении предоставленного решения, но не согласен с объяснением: "реализация" не является "преобладающий", как сказал здесь
@ HJuls2 действительно, поскольку вы можете переопределить метод абстрактным методом без реализации ...
@Holger Да, то, что вы говорите, разрешено, но, честно говоря, я не вижу реального использования этого сценария ...
@ HJuls2 ну, может быть, унаследованная реализация не подходит для конкретного контракта, и подклассы должны переопределить ее другой реализацией. Иногда абстрактный метод переопределяет другой абстрактный метод только для того, чтобы иметь комментарий к документации, содержащий описание расширенного контракта.
Это зависит от того, что вам нужно делать, и от необходимого вам уровня совместимости с ReadableImpl.
Вы можете создать подкласс ReadableImpl и переопределить doThis:
public class ReadableImpl2 extends ReadableImpl {
@override
public void doThis() {
System.out.println("do this 2");
}
}
Если у вас нет доступа к экземпляру, вы можете использовать прокси:
public class ReadableProxy implements Readable {
private final Readable delegate;
public ReadableProxy(Readable delegate) {
this.delegate = delegate;
}
public void doThis() {
System.out.println("do this proxy");
}
public void doThat() {
delegate.doThat();
}
}
Ваш вопрос
What should I do if I want to override method doThis()? Should I implement Readable in another class?
Я думаю, это не совсем понятно из-за некоторого смешения в именах операций, связанных с расширениями / реализациями. Итак, позвольте мне попытаться ответить на ваш вопрос, объяснив все вокруг на вашем примере:
public interface Readable {
void doThis();
void doThat();
}
Имея такой интерфейс, вы можете implement его методы в выбранном вами классе, используя ключевое слово implements.
public class ReadableImpl implements Readable {
public void doThis() {
System.out.println("do this");
}
public void doThat() {
System.out.println("do that");
}
}
Теперь, если вы хотите использовать этот метод для override, единственный способ сделать это - создать новый класс, который extendsReadableImpl, потому что to override означает изменить функционал метода родительский класс в дочерний класс:
public class ReadableImplChild extends ReadableImpl{
@Override
public void doThis() {
System.out.println("do this more specific way");
}
@Override
public void doThat() {
System.out.println("do that more specific way");
}
}
Но если вам нужен совершенно другой способ обработки этого, что ReadableImpl обрабатывает методы интерфейса Readable, вы должны создать новый класс, который будет implement для этого интерфейса введение нового функционала
public class ReadableTotallyDifferentImpl implements Readable {
public void doThis() {
System.out.println("do this totally another way");
}
public void doThat() {
System.out.println("do that totally another way");
}
}
Вы можете (я знаю, что вы не хотите, но можете) overload методом. А значит создать новую версию той же функции, которая отличается только по количеству и / или типу параметров метода.
public class ReadableImpl implements Readable {
public void doThis() {
System.out.println("do this");
}
public void doThat() {
System.out.println("do that");
}
/**
* this is funciton overloading
*/
public void doThat(String userSpecific) {
System.out.println("do that for:" + userSpecific);
}
}
Согласно вашему вопросу:
What should I do if I want to override method doThis()?
Смотря как:
ReadableImpl, но вы хотите, чтобы этот метод работал по-другому, можно либо перегрузить это,
или изменить его реализацию
Что именно ты хочешь здесь делать? Вы имеете в виду два поведения для
doThis()или что-то еще?