Я создал библиотеку, которая простирается от другой библиотеки, написанной на C++, и теперь я переношу эту библиотеку на Java (исходная библиотека, которую C++ была написана поверх уже существующей в Ява). В коде C++ существует чисто виртуальный класс под названием Stallable
, который предполагается использовать для того, чтобы добавить обнаружение сваливания на контроллер двигателя с учетом дельта входного напряжения. Класс содержит чисто виртуальный метод getVoltage()
, который используется для подачи источника напряжения, поскольку он представляет собой несколько различных классов контроллеров двигателей, и некоторые виртуальные функции, чтобы определить, есть ли стойло.Портирование множественного наследования Код C++ для Java
Классы будут подклассифицировать этот класс, а также класс из исходной библиотеки (тот, который у меня не имеет доступа к коду, и для всех целей и задач иначе не может быть изменен) и будет реализовывать getVoltage()
и переопределить любые другие методы, которые им могут понравиться. Тогда эти объекты можно просто спросить, есть ли стойло.
Когда я подхожу к этой проблеме со стороны Java, ситуация становится немного сложнее. Я до сих пор не могу коснуться оригинального класса, поэтому рефакторинг кода не является вариантом, и пользователям моей библиотеки все равно разрешено подклассы или реализовать Stallable
, но они сочтут нужным.
В настоящее время перспективы, которые я вижу, следующие.
- Сделайте
Stallable
интерфейсом и воспользуйтесь логикой обнаружения останова, которую он использует. Чтобы создать исходную функциональность, которую имеет кодовая база C++, мне пришлось бы иметь подклассы классов исходной библиотеки и реализоватьStallable
. Это сработает, но потребует повторной реализации логического элемента в чисто виртуальном C++Stallable
среди любых подклассов, которые я бы включил, и любых подклассов, которые будут писать конечные пользователи. - Сделайте
Stallable
абстрактным классом, который содержит ссылку на объект класса контроллера двигателя из исходной библиотеки. Это сохраняет некоторые функциональные возможности кода C++, поэтому некоторые методы должны быть переопределены, а некоторые необязательно переопределены, однако прозрачность теряется между этим кодом и кодом C++. В C++, поскольку каждый подкласс былStallable
и выводом исходного контроллера двигателя, стало легко бросать указатели на объект, когда требуется контроллер двигателя, и когда нужен объектStallable
. В этом случае должен быть реализован некоторый тип функции доступа, который возвращает ссылку Java на исходный контроллер мотора, к которому будет принадлежать подклассStallable
. Прозрачность будет потеряна, но обнаружение сваливания будет легко добавлено.
Очевидно, что если бы я мог модифицировать исходные классы для различных контроллеров двигателей, эта проблема может быть легко реорганизована на код C++.
После изучения несоответствий между подходами обоих языков к ООП, я склонен идти с вариантом 2, несмотря на трение, которое он добавляет для моих конечных пользователей, и реализованные в нем варианты Stallable
, которые я планирую включить. Я спрашивал, есть ли какие-нибудь другие идеи или идеи, прежде чем я начну писать Stallable.java.
Вы абсолютно правы в несоответствии между подходами ООП. Однако у Java есть статический импорт: это может быть использовано для уменьшения объема кода, который должны реализовать ваши клиенты, если вы решили использовать интерфейс. Если вы добавили класс декоратора над этим интерфейсом, вы могли бы реализовать свои чистые виртуальные функции. Кроме того, вы можете посмотреть Java Native Access (https://github.com/twall/jna). –
вы можете сделать это в java8. Stallable - это интерфейс с одним абстрактным методом getVoltage() и другими методами «по умолчанию», которые содержат тела методов. – ZhongYu
@ zhong.j.yu Я реализую решение таким образом. Я не знал об этой возможности, спасибо. –