Как лучше всего расширить функциональные возможности класса?
Предположим, у меня есть класс под названием Task. Я хочу добавить к нему некоторые дополнительные функции, поэтому я расширяю его. Я делаю это, создавая класс, который расширяет задачу.
public class TaskHelper extends Task
{
public void getName()
{
....
}
// more additional functionality
}
Итак, я начинаю использовать это, и когда у меня есть объект task, и опускается до TaskHelper, я получаю ClassCastException. Поэтому я понимаю, что не могу унывать, и я пытаюсь создать копию конструкции что-то вроде
public class TaskHelper extends Task
{
TaskHelper(Task t)
{
Task(t);
}
}
Однако для задачи нет конструктора копирования, и я не могу изменить задачу, потому что это класс третьей стороны. Что я могу сделать?
4 ответа:
Я не могу изменить задачу, потому что это сторонний класс
Task
это внешняя зависимость. Вместо того чтобы расширять его, абстрагируйте его. Что-то вроде этого:public class TaskHelper { private Task task; public TaskHelper() { task = new Task(); } // expose methods to delegate functionality to the private member }
Это позволяет отделить ваш код от кода третьей стороны. Это приносит ряд преимуществ:
- вы можете упростить интерфейс для стороннего компонента, предоставив только необходимую функциональность или переименовав функциональность в соответствии с вашим доменным языком
- вы можете имейте
TaskHelper
реализовать интерфейс, который может быть легко высмеян для модульного тестирования или заменен другими реализациями задачи- вы можете объединить функциональность с другими связанными вещами и расширить компонент, все еще инкапсулируя его в этот объект
Если я правильно понял ваш вопрос, у вас есть объект Task где-то в коде и вы хотите предоставить ему дополнительную функциональность, расширив сам класс Task. Ну, для меня это звучит так, как будто вам нужен какой-то класс обертки. Я бы создал TaskHelper следующим образом:
public class TaskHelper { private Task taskObject; private String name; //Additional variables public TaskHelper(Task t) { taskObject = t; } public Task getTaskObject() { return taskObject; } //Setters, Getters and other methods working on the Task object and additional variables }
Теперь вы можете получить доступ к объекту задачи через геттер и работать с ним в обычном режиме, а также использовать новые методы для работы с объектом задачи.
Если вам нужна возможность обработайте TaskHelper как обычный объект задачи, вам нужно расширить класс задачи, но это тоже легко. Просто создайте класс TaskHelper, как вы написали, и вызовите метод super () (который вызывает конструктор суперклассов..) вместо вашей задачи (Т). Убедитесь,что вы также предоставляете всю информацию, необходимую конструктору задачи в конструкторе TaskHelper.
Надеюсь, это вам немного помогло.
Лучший дизайн-это использование композиции.
public class TaskHelper { Task task; }
Вы сможете использовать любой вид задачи, используя этот подход.
Здесь задача должна быть интерфейсом.
Согласно Вашему вопросу
Class Task
- это класс 3-й стороны, где вы не можете изменить его реализацию. Вы пробовали, можете ли вы "увидеть" методыTask
изTaskHelper
после того, как вы расширяетеTask
?class TaskHelper extends Task { }
Приведенный выше код неявно наследует все методы и члены от Task до TaskHelper. Таким образом, вам больше не нужно явно / вручную пытаться расширить методы суперкласса.
Вы также упомянули, что нет конструктора из класса Task. Тем не менее, есть всегда пустой конструктор по умолчанию, который не принимает никаких аргументов.
Кое-что дополнение: Если вам нужно получить доступ к любому из членов класса super или вызвать конструктор из класса super, вы можете использовать ключевое слово
super
.Пример использования "супер":
class A //A is super Class { private int a; public A(int a) { this.a = a; } } class B extends A //B is sub Class { private int b; public B(int a, int b) //a inherited from Class A { super(a); //use "super" to call the constructor from super class this.b = b; } }