Почему вы можете привести к абстрактному классу - PullRequest
3 голосов
/ 12 июня 2011

Я читаю книгу о структурах данных в Java, и сейчас речь идет об итераторах. Я видел следующий код, и он кажется мне странным. В следующем коде AbstractIterator - это абстрактный класс, который реализует Iterator<E>, UniqueFilter - это подкласс AbstractIterator, который не является абстрактным, а data - это вектор. Думаю, я не понимаю, как в первой строке вы можете взять выходные данные метода Vector.iterator () и преобразовать их в абстрактный класс. После строки 1 dataIterator не является экземпляром абстрактного класса?

AbstractIterator<String> dataIterator =
    (AbstractIterator<String>)data.iterator();
AbstractIterator<String> ui = new UniqueFilter(dataIterator);

Ответы [ 6 ]

3 голосов
/ 12 июня 2011

Проблема в том, что мы говорим о двух разных типах. Тип (время выполнения) объекта и тип (время компиляции) ссылки.

  1. dataIterator - это ссылка на абстрактный тип - это нормально.
  2. data.iterator() возвращает ссылку на объект, тип которого не ясен из примера, но, очевидно, это конкретный тип, который наследуется от AbstractIterator<String> - это нормально
  3. Вы всегда можете присвоить ссылку на объект типа B ссылке на объект типа A, если B является дочерним элементом A, даже если A является абстрактным (или интерфейсом). Тебе на самом деле не нужен актерский состав.

Таким образом, после первой строки dataIterator все еще является ссылкой типа AbstractIterator<String>, но это ссылка на объект конкретного типа, который реализует AbstractIterator<String>.

Помните, что в JAVA все переменные объекта на самом деле являются ссылками.

UniqueFilter не имеет значения для этого вопроса, кстати.

0 голосов
/ 12 июня 2011

HeadofState - абстрактный (по английскому значению слова абстрактный) термин.

Нет ни одной страны в мире, где официальное название главы государства - глава государства.

Глава государства, хотя и абстрактно по языку и существованию, является суперклассом или суперкатегорией титулов, таких как султан, президент, премьер, премьер-министр, любимый отец и т. Д.

Таким образом, даже если существование главы государства не может быть реализовано в его абстрактной форме, вы можете создать экземпляр (демократическим путем, по наследству или путем переворота) президента, премьер-министра или любого другого человека. .

Так, например, был создан премьер-министр, его можно приравнять к его абстрактной родительской терминологии "Глава государства".

Таким образом, хотя экземпляр абстрактного класса не может быть создан, реализация этого абстрактного класса может быть реализована. Вот что могут сделать фабрики. Фабрики являются средством создания экземпляров абстрактных классов.

Так же, как абстрактные классы, интерфейсы не могут быть созданы, но должны быть реализованы. Абстрактные классы реализованы частично, тогда как сами интерфейсы полностью не реализованы. Абстрактные классы и интерфейсы зависят от производных классов для завершения их существования. Конечно, техническая терминология навязчивого OO-пуриста прояснит, что абстрактные классы «расширены», а интерфейсы «унаследованы».

Например, HttpServletRequest - это интерфейс. Вы не можете создать экземпляр этого напрямую. Когда ваш JSP получает запрос http-сервлета, он работает одинаково, независимо от того, используете ли вы Jetty или Tomcat. Однако, если вы внимательно осмотрите, фактический класс, созданный фабрикой HttpServletRequest в Jetty, отличается от класса, созданного в Tomcat. Но, поскольку оба они реализуют HttpServletRequest, эти экземпляры можно просто приравнять к переменной, тип которой HttpServletRequest.

Вы должны прочитать об абстрактных классах по сравнению с интерфейсами и о том, как интерфейсы составляются для обеспечения псевдо-множественного наследования в Java. Как только вы поймете роль интерфейсов, вы поймете абстрактные классы. В сфере объектно-ориентированных пламенных войн некоторые люди думают, что интерфейсы были блестящим прорывом в множественном наследовании. Некоторые люди думают, что интерфейсы не имеют ничего общего с множественным наследованием. По моему собственному, менее скромному мнению, интерфейсы - плохая и неудавшаяся попытка социалистической патерналистской снисходительности предотвратить меня от неприятностей, которые предполагают, что я не знаю, как заботиться о себе.

0 голосов
/ 12 июня 2011

Из того, что вы описали, похоже, что можно сделать предположение, которое было упущено;что реализующий тип, возвращаемый data.iterator(), здесь является подклассом AbstractIterator<String>.

Если это предположение может быть сделано, то первое утверждение становится очевидным, поскольку объект может быть юридически приведен к типу любого объекта доиерархия наследования, в данном случае AbstractIterator<String>.

В этом случае dataIterator НЕ является экземпляром абстрактного класса;здесь он не создается (то есть new AbstractIterator<String(...)), это просто ссылка на экземпляр, возвращаемый Vector.iterator() с типом суперкласса фактического возвращаемого типа, который оказывается абстрактным классом.

0 голосов
/ 12 июня 2011

После строки 1, dataIterator не является экземпляром абстрактного класса?

Это экземпляр UniqueFilter, который также делает его AbstractIterator наследованием.Попытка «создать экземпляр и экземпляр абстрактного класса» означает попытку вызвать конструктор абстрактного класса, это то, что не разрешено, и это то, что здесь не происходит.

0 голосов
/ 12 июня 2011

Абстрактный класс - это класс, создание которого невозможно.Часто он будет включать один или несколько методов, которые также объявлены абстрактными и должны быть реализованы подклассами, чтобы подкласс был конкретным (противоположным абстрактному) и, следовательно, мог быть реализован.

UniqueFilter является подклассом AbstractIterator (абстрактный класс).Так как это тип отношений IS-A, вы не можете объявить экземпляр абстрактного класса.

Если вы хотите создать экземпляр для абстрактного класса, сначала вы создаете конкретный подкласс, создаете для него экземпляр и используете его.

0 голосов
/ 12 июня 2011

Наследование означает IS-A.Если Child наследует от Parent, то Child IS-A Parent и может использоваться в любой ситуации, когда требуется Parent.это так, как показывает ваш код.

Почему бы вам не поверить JVM?

...