метод не переопределяет, так как тип параметра отличается. Вы должны объявить метод как это:
public class GoldenRetriever extends Animal {
public void fetch(Animal pup) {
т.е. тип параметра еще должен быть Animal
, даже если вы пишете класс, который расширяет Animal
.
Для этого есть веская причина. Предположим, у вас есть какой-то другой метод
public void someMethod(Animal x)
Вы можете пройти любой Animal
в качестве параметра, в том числе GoldenRetriever
:
GoldenRetriever gr = ...;
someMethod(gr);
Предположим, что в someMethod
у вас это:
public void someMethod(Animal x) {
FelineCat kitty;
...
x.fetch(FelineCat);
С Animal
метод fetch
может принимать любые Animal
, компилятор считает, что он должен быть OK, чтобы сделать этот вызов, потому что FelineCat
- это Animal
. Он не знает, что x
на самом деле GoldenRetriever
.Если бы это позволило переопределяющему методу принять параметр GoldenRetriever
, возникла бы проблема, так как этот параметр фактически равен FelineCat
, а не GoldenRetriever
. Итак, когда fetch
называется полиморфно, а тип параметра ошибочен, то что?
У компилятора нет возможности предотвратить это, поскольку он не знает, что такое тип x
. Теоретически Java может разрешил переопределять изменение типа параметра и сделал проверку во время выполнения (возможно, выбрасывая ClassCastException
, если он попытался получить GoldenRetriever
, чтобы получить другой вид Animal
). Я не знаю, почему они этого не сделали, но я уверен, что есть веские причины не делать этого таким образом.
Но вы можете сделать свой собственный контроль выполнения:
public class GoldenRetriever extends Animal {
public void fetch(Animal pup) {
if (pup instanceof GoldenRetriever) {
GoldenRetriever puppy = (GoldenRetriever)pup;
// now puppy is viewed as a GoldenRetriever, and any methods or
// instance variables particular to GoldenRetrievers can be accessed
} else {
throw new WrongSpeciesException("..."); // or whatever
}
}
}
UPDATE: выше ответ предполагает, что метод подписи действительно то, что вы хотите. Но, следуя комментарию Mixone, может быть, что вы - , а не, пытающийся настроить операцию, которая включает в себя двух животных, и в этом случае у вас не должно быть параметра вообще. Способ, как
public void fetch(GoldenRetriever pup)
предполагает, что у вас есть один GoldenRetriever
, что будет делать что-то с другой GoldenRetriever
, и что вы просто не хотите GoldenRetriever
делать это с другими видами животных. В этом случае я считаю, что проверка времени выполнения - лучший подход. Но если вы хотели операцию, которая работала только на одном животном, вы написали это неправильно.
Что делать, если у вас есть 'Animal' класс с подпись, подобная этому методу 'Animal' и 'Animal'' метод 'fetch' принимает параметр типа' T'. Тогда все ваши подклассы могут иметь метод «выборки» с их собственным типом. Так, например, 'public class FelineCat extends Animal ' class имеет подпись метода 'void fetch (FelineCat kitty)' like this –
Bunti
Не ваш метод выборки, просто используя сам объект? как в этом или в себе, поэтому нет необходимости в обработке параметров, метод является внутренним – Mixone