2015-01-21 3 views
4

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

+0

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

+0

Возможно, вы можете показать нам некоторые из созданных вами «CommonExcelFunctions». – user3437460

+0

да, прочитав другие ответы, статические - это то, что я собираюсь сделать. есть ли способ избежать ввода имени класса каждый раз? , поэтому вместо int s = CommonExcelFuntions.GetLastRowNum(); Я могу положить: int s = GetLastRowNum(); ? –

ответ

0

Вы должны всегда предпочитают композицию для наследования. Ваш новый класс не является «CommonExcelFunctions», он просто использует функции CommonExcelFunctions. Вероятно, вы не будете вызывать функции из CommonExcelFunctions в экземплярах вашего нового класса. Не нужно загрязнять интерфейс вашего нового класса методами из CommonExcelFunctions. Это сломает инкапсуляцию.

Когда вы используете композицию, вы можете легко тестировать классы, которые используют CommonExcelFunctions, передавая макет.

Когда вы используете наследование, очень сложно протестировать ваш класс (частичные издевки сосать).

Например, go language не поддерживает наследование вообще.

См. Эффективный java, пункт 16 «Офорт композиции над наследованием».

+2

Я не думаю, что «всегда» уместно. В большинстве случаев, да, но не всегда. – Sid

+1

Я сказал «всегда предпочитаю» не «всегда использовать»: P – woru

4

Никогда не используйте наследование только ради повторного использования кода. Отношение подкласса должно быть значимым отношением is-a, особенно на языке Java, где у вас есть только однонаследование.

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

+0

спасибо, это то, что я хотел знать. вопрос, если я использую его как статичный, существует ли способ избежать необходимости вводить имя класса каждый раз, когда мне нужно использовать функцию? могу ли я сделать так, чтобы я мог использовать: FindLastRow(); вместо: CommonExcelFunctions.FindLastRow(); –

+0

Да, см. [Статический импорт] (https://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html), но его следует использовать очень осторожно, поскольку это приводит к загрязнению локальное пространство имен, то есть вы можете столкнуться с амбициозными именами. –

2

Как и в случае с @AlexisKing, я часто создаю класс утилиты (например, ExcelFunctionsUtil и создаю кучу static методов там. Это хорошо, когда код должен быть повторно использован в нескольких местах, но наследование doesn ' я считаю, что наследование имеет смысл только в том случае, если подкласс действительно может считаться расширением или дочерним типом родительского класса. Например, если вы создали класс UncommonExcelFunctions, который, казалось бы, был бы подходящим дочерним элементом CommonExcelFunctions, но класс Accounting не имеет смысла.

1

Обычно, когда мы сомневаемся, мы задаем себе основы. Имеем ли отношение is-a или has-a relatio nship.

Если ваши новые классы действительно имеют отношение is-a к вашему классу CommonExcelFunction, то вы, вероятно, можете его продлить.

Чтобы ответить на ваш первый вопрос - Лучшее время для продления класса.

Иначе, если он действует как служебный класс, и некоторые примеры, такие как те, которые предусмотрены в Java (Пример: Math.max, Math.min). Вы можете реализовать свои методы в классе как static (Для использования метода не требуется создание экземпляра).

Подумайте об этом:

Scanner scn = new Scanner(System.in); //Scanner class using instance methods 
Math.max() //Math class using static methods 

Почему Java хотят реализовать методы в сканере, как нестатической в то время как в Math class, как статического? Вероятно, вы знаете ответ, если потратите некоторое время, чтобы подумать об этом.

Не обязательно, если у вас есть некоторые методы, которые мы хотим использовать непосредственно, например (получить показатель числа, получить максимум 2 числа, округляя значение ..etc).

Однако это имеет смысл для создания методов экземпляра (например Scanner class), когда мы, возможно, потребуется больше, чем один тип сканера (Пример: сканирование консольного ввода, сканирования из файла).

Смежные вопросы