Расширить класс, у которого нет конструктора - PullRequest
0 голосов
/ 14 марта 2019

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

Проблема в том, что у класса Car нет конструктора, поэтому я не могу использовать super, единственный способ создать объект Car - использовать нативный метод, который возвращает полностью заполненный объект Car.

public class Car {
    //The only way to create a car  
    public native Car readFromFile (String file);

    //Many other variables and methods

}

И мой пользовательский класс:

import com.example.Car;

public class CustomCar extends Car {
    public void extraMethod1(){
        //do something using Car variables
    }
}

Очевидно, что я не могу привести к (CustomCar), поскольку у меня есть ClassCastException, так как я могу получить Car из этого нативного метода и использовать на этом объекте методы из CustomCar?

Должен ли я просто иметь переменную Car в CustomCar и использовать ее в методах CustomCar?

import com.example.Car;

public class CustomCar {
    Car car;
    public void extraMethod1(){
        car.doSomething(); //do something using Car variables

    }
}

Или мне просто создать новый конструктор, копирующий все родительские переменные?

Большое спасибо за вашу помощь!

1 Ответ

1 голос
/ 14 марта 2019

Я подозреваю, что ваш вопрос может быть основан на неправильном представлении. Ваш пример класса Car имеет конструктор по умолчанию, который эквивалентен написанию этого:

    public Car() { }

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

Если вы объявите CustomCar в качестве подкласса Car, он может использовать конструктор Car по умолчанию.


Вторая проблема заключается в том, что вы объявили readFromFile как

    public native Car readFromFile (String file);

должно быть

    public static native Car readFromFile (String file);

для использования. (Если readFromFile действительно является методом экземпляра и действительно единственным способом создания Car экземпляров, тогда у вас возникла проблема с начальной загрузкой. Как создать первый Car?)


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

  • Если CustomCar(...) просто использует Car(), суперкласс не будет правильно инициализирован.

  • Если это класс Car.readFromFile(), результатом будет новый объект Car, а не CustomCar.

Возможно, есть несколько способов обойти это. Например:

  • Вы можете добавить явный конструктор к Car, который выполняет необходимую инициализацию.

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

Какой подход лучше? Трудно сказать. Это зависит от деталей вашего реального варианта использования; например имеет ли объект, созданный нативным методом, скрытое состояние или специальные свойства, связанные с идентификацией? (Почему вы создаете его, используя собственный код?)


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

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