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

Безопасность данных подкласса при возврате в качестве суперкласса

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

    public class SuperClass
    {
        int a;
    }
    public class SubClass extends SuperClass
    {
        int b;
    }


    SuperClass superObj;
    SubClass subObj;

    private SuperClass getObject ()
    {
        return subObj;
    }


    public static void main (...)
    {
        superObj = getObject();
    }

Что именно происходит с subObj, когда он возвращается в качестве своего суперкласса? При вводе этого примера я понимаю, что, вероятно, мог бы так же легко протестировать его сам, но мне все еще любопытно, каков именно процесс, когда это происходит, и считается ли он хорошим (если он работает, то есть) или плохой практикой .

Я спрашиваю, потому что сейчас работаю над проектом, в котором у меня есть два абстрактных базовых класса и несколько подклассов для каждого из них. Я пытаюсь найти хорошие/плохие способы справиться с необходимостью перехода от одного подкласса к другому, все еще используя полиморфизм удобства, который добавляется при использовании абстрактных базовых классов.

РЕДАКТИРОВАТЬ: я исправил основные объявления и объявления классов, извините за это.


Ответы:


1

В вашем коде есть некоторые странности (определение метода внутри main?), но не смотря на это... Метод getObject не изменит ваш subObj, он просто вернет ссылку на него, которая выглядит как тип SuperClass. Под «похожим» я подразумеваю, что он будет раскрывать только любые методы или члены из SuperClass. Однако, если вы возьмете это возвращаемое значение и попытаетесь понизить его до подкласса, приведение будет успешным, и вы обнаружите, что поле/методы из подкласса будут работать так, как вы ожидаете, без какой-либо потери информации из-за того, что они были возвращены как суперкласс.

25.07.2013

2

Приведение принципиально не меняет объект на другой тип, оно просто говорит компилятору рассматривать объект как его суперкласс (или подкласс при понижении). В вашем примере superObj по-прежнему является экземпляром типа SubClass, но теперь он выглядит как SuperClass. Это означает, что если вы попытаетесь сослаться на superObj.b, вы получите ошибку компиляции (поскольку b не существует в SuperClass). Однако вы можете сослаться на (SubClass)superObj.b. В этом случае вы говорите компилятору рассматривать подкласс как экземпляр подкласса (что на самом деле и есть).

Давайте сделаем еще один шаг и добавим еще один класс в ваш код:

public class SisterClass extends SuperClass
{
    int c;
}

Ничего не меняя в коде (кроме проблем с синтаксисом), вы пытаетесь сослаться на ((SisterClass)superObj). Это скомпилируется, но завершится ошибкой времени выполнения ClassCastRuntime. Хотя SisterClass является подклассом SuperClass, superObj не является экземпляром SisterClass. Таким образом, вы можете привести только к тому, что объект на самом деле является.

25.07.2013

3

Подкласс является расширением Суперкласса

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

Возвращаемый класс будет иметь a, но не b.

25.07.2013
  • Тем не менее, стоит отметить, что если у вас есть ссылка на объект типа SuperClass, то Java позволит вам опросить его, чтобы определить, является ли он более конкретным типом (в данном случае SubClass), и позволит вам приводить вниз, где это уместно. 25.07.2013
  • @tuckermi это указывало бы на плохой дизайн, если бы вы вернули базовый тип в первую очередь. 25.07.2013
  • Хотя это часто верно, безусловно, есть случаи, когда заброс вниз приемлем. И, что более важно, я думаю, что это стоит упомянуть, потому что оно подчеркивает, что делает JVM, по сравнению с тем, как может обрабатываться приведение вверх в других языках/средах выполнения. 25.07.2013
  • Новые материалы

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

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

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

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

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

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

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