В java мы можем сузить тип возвращаемого значения и тип исключения throws (или даже стереть предложение throws):
abstract class A
{
abstract CharSequence getName() throws NameNotAvailableException;
}
class B extends A
{
String getName()
{
return "foo";
}
}
Но как насчет типов параметров (если A принимает T
, то почему B не принимает ? super T
), как в:
abstract class A
{
abstract void setName(final String name);
}
class B extends A
{
void setName(final CharSequence name)
{
}
}
Давайте рассмотрим этот фрагмент кода, который, как мне кажется, полностью логичен для меня:
void handleA(final A a)
{
a.setName("foo");
}
handleA(new B());
Итак, я говорю, что B
все еще действителен в контексте кода, использующего A
.
Потому что CharSequence
- это не только String
, а String
- это CharSequence
. Другими словами, CharSequence
также может быть CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
.
Вот почему вы не можете изменить тип параметра setName(String)
на CharSequence
.
Я предполагаю, что это ограничено из-за сложностей, которые он добавит с разрешением метода, когда есть также перегруженные методы с аналогичными подписями.