Nano Hash - криптовалюты, майнинг, программирование

Можете ли вы переделать абстрактный метод в дереве наследования?

РЕДАКТИРОВАТЬ:

Чтобы было ясно: тот факт, что дизайн довольно уродлив, не имеет значения. Дело в том, что дизайн есть, и я должен добавить еще один подкласс FlyingMotorizedVehicle, который не будет работать должным образом, если я забуду добавить foo(...). Поэтому мне просто было интересно, могу ли я переопределить его как абстрактный.


Я сейчас сталкиваюсь с довольно странной ситуацией наследования. Допустим, у меня есть три класса: Vehicle, MotorizedVehicle и FlyingMotorizedVehicle, а также несколько классов Airplane, Helicopter,...:

public abstract class Vehicle {

    abstract Something doStuff(...);

    abstract SomethingElse doOtherStuff(...);

    abstract Foo bar(...);

}

public class MotorizedVehicle extends Vehicle {

    @Override
    Something doStuff(...) {
        return new Something();
    }

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

    @Override
    Foo bar(...) {
        return new Foo();
    }

}

public class FlyingMotorizedVehicle extends MotorizedVehicle {

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

}

public class Airplane extends FlyingMotorizedVehicle  {

    @Override
    Foo bar(...) {
        //do something different
        return new Foo();
    }

}

public class Helicopter extends FlyingMotorizedVehicle {

    @Override
    Foo bar(...) {
        //do something totally different
        return new Foo();
    }

}
[...]

Итак, Vehicle — это абстрактный класс, предоставляющий некоторые абстрактные методы. MotorizedVehicle является подклассом Vehicle с конкретными реализациями его методов. FlyingMotorizedVehicle снова является подклассом MotorizedVehicle, переопределяющим реализации подмножества методов MotorizedVehicles.

Теперь есть подклассы Helicopter, Airplane и, возможно, некоторые другие, которые в примере переопределяют конкретную реализацию MotorizedVehicle#bar(...). Я хочу «заставить» каждый подкласс MotorizedVehicle переопределять метод bar(...) и предоставлять свою собственную реализацию.

Можно ли просто изменить FlyingMotorizedVehicle следующим образом:

public class FlyingMotorizedVehicle extends MotorizedVehicle {

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

    abstract Foo bar(...);

}

Так что я просто переопределяю bar(...) как абстрактный метод? Моя IDE на это не жалуется, но это, конечно, не значит, что она действительно будет работать.

Надеюсь, вы поняли, на что я пытаюсь указать здесь.

заранее спасибо

блудди


  • Ваша IDE должна жаловаться, потому что FlyingMotorizedVehicle не является абстрактным, а неабстрактные классы не могут содержать абстрактные методы. В противном случае я это возможно. Вы можете использовать его, чтобы заставить другой подкласс повторно реализовать метод. Я сделал это, например. с equals() и hashCode() несколько раз. 04.07.2014
  • Imho, более понятно реорганизовать это в шаблон Template method, используя doStuff(), ..., bar() в качестве методов шаблона и иметь отдельные реализации всех подклассов. Если вы хотите разделить некоторый код между подклассами, поместите этот код в protected static метода. 04.07.2014

Ответы:


1

Да, вам нужно переопределить bar(...) как абстрактный метод. Затем вы также должны объявить public class FlyingMotorizedVehicle абстрактным классом.

public abstract class FlyingMotorizedVehicle extends MotorizedVehicle {

    @Override
    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    }

    abstract Foo bar(...);

}
04.07.2014

2

Вы хотите, чтобы дочерние элементы MotorizedVehicle имели реализацию по умолчанию bar, но не для дочерних элементов FlyingMotorizedVehicle.

abstract class BasicMotorizedVehicle
    // no bar
    ... // Rest of old MotorizedVehicle

class MotorizedVehicle extends BasicMotorizedVehicle
    Foo bar(...) { ... }

class FlyingMotorizedVehicle extends BasicMotorizedVehicle
04.07.2014

3

Брат, изучай и Интерфейсы.

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

И сделайте свой FlyingMotorizedVehicle абстрактным классом.

  • Абстрактный класс может иметь оба типа функций: либо только прототип (абстрактные функции), либо полностью реализованные функции.
  • Интерфейсы имеют только прототипы функций, они не могут содержать реализации функций. Интерфейсы должны быть реализованы.

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

============================ПРИМЕР КОДА================== ======================

Для автомобиля

public interface Vehicle {

    Something doStuff(...);   
    SomethingElse doOtherStuff(...);
    Foo bar(...);

}

Для летающих моторизованных транспортных средств

public abstract class FlyingMotorizedVehicle extends MotorizedVehicle {

    SomethingElse doOtherStuff(...) {
        return new SomethingElse();
    } 
}

===============================================================================

Удачной ООП-игры!

04.07.2014
  • Спасибо за подсказки, однако, вопрос был не об иерархии здесь или дизайне всего этого. Пример также очень короткий... абстрактный класс Vehicle предлагает реализации, а также абстрактные прототипы. Может быть, многие I в моем вопросе сбивают с толку, но я этого не придумал. Я только что столкнулся с тем, что хотел добавить один из подклассов (то есть еще один летательный аппарат) и забыл переопределить foo, что привело к поведению, которое мне не понравилось :) 04.07.2014
  • @Bluddymarri На самом деле это проблема дизайна, приятель. :) 04.07.2014

  • 4

    Да, ты можешь. Фактически, в нем даже говорится, что вы можете явно в спецификации языка:

    Метод экземпляра, который не является абстрактным, может быть переопределен абстрактным методом.

    Проблема, с которой вы столкнулись, описана несколькими абзацами выше:

    Объявление абстрактного метода должно появляться непосредственно внутри абстрактного класса (назовем его А), если только оно не встречается в объявлении перечисления (§8.9); в противном случае возникает ошибка времени компиляции.

    Итак, проблема в том, что ваш класс не является абстрактным, как уже указывали другие; может быть просто полезно знать конкретные части спецификации, которые его описывают.

    16.10.2018
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..