Ошибка в наследовании - PullRequest
1 голос
/ 20 июля 2011

У меня есть интерфейс BaseModel

public interface BaseModel
{
    String toString();
}

и абстрактный класс BaseData

public abstract class BaseData
{
    public abstract String toString();
}

Я хочу, чтобы мои классы моделей переопределяли метод toString().Для этого я попробовал следующие способы, по одному, но не вместе:

  1. Заставить все мои классы модели реализовать interface BaseModel

  2. Заставьте все мои классы модели реализовать abstract class BaseData

В первом случае я не получаю ошибку компиляции, если не переопределить метод toString() в моем классе модели.Я предполагаю, что он рассматривает метод Object.toString() как допустимую реализацию.

Но во втором случае, если я не переопределю метод toString(), я получаю ошибку компиляции:

Тип Title должен реализовывать унаследованный абстрактный метод BaseData.toString()

, где Title - один из классов моей модели, который расширяет BaseData, но не переопределяет toString().

Почему расхождение?

Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 20 июля 2011

Когда вы вызываете toString из вашего интерфейса, JVM будет искать метод toString в вашем классе Title и всех его расширенных классах.например.Продолжайте поиск, пока он не достигнет конца дерева = Класс объекта.

                       Object.class - found toString
                           |
Interface.class   ---  Title.class - can't find toString

В Java вы можете расширить только 1 класс.Таким образом, ваш абстрактный класс расширяет Object.class и переопределяет метод toString.Sincs Title расширяет ваш абстрактный класс, он не может сам расширять Object.class.

Object.class
     |
Abstract.class - overrides toString
     |
Title.class - has to override toString as it is abstract
2 голосов
/ 20 июля 2011

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

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

Исключением из этого правила является наличие абстрактного класса A , который имеет подкласс B (который также является абстрактным), а B имеет подкласс C . B не нужно реализовывать метод toString , пока C реализует его.

1 голос
/ 20 июля 2011

В случае 1 вы определяете новый интерфейс (с помощью toString ()), а затем реализуете его. Как вы и сделали, поскольку ваши объекты расширяют Object, а Object также определяет toString (), любой подкласс Object будет соответствовать вашему интерфейсу.

В случае 2 вы определяете абстрактный класс с помощью абстрактного метода toString (), который скрывает метод суперкласса (Object). В этом случае ваши подклассы BaseData должны определить реализацию нового абстрактного метода toString ().

1 голос
/ 20 июля 2011

Потому что ваш унаследованный класс конкретен.В этом случае он должен реализовать все методы abstrct, объявленные в интерфейсе, который он реализует, и абстрактные классы, которые он расширяет.

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

0 голосов
/ 20 июля 2011

Каждый объект имеет метод toString(), поэтому, если вы реализуете BaseModel, он уже выполняет контракт интерфейса.Но BaseData вы специально делаете метод абстрактным, поэтому каждый подкласс должен переопределять его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...