2016-08-10 2 views
6

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

Мне просто интересно, существует ли аналогичная функция на Java? или это единственный способ добавить дополнительные методы к существующему классу Java - создать подкласс существующего класса?

+2

Не на Java. Однако не все довольны тем, что говорят в Scala. Поскольку это может затруднить читаемость, ремонтопригодность. Обычно он создает класс с функциями, такими как XxxUtils или Xxxs. Наследование имеет свои проблемы там (конечные классы, принудительная усталость старого кода, централизм = только одна точка расширения). –

ответ

5

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

Вы можете использовать аннотации @ExtensionMethod для «преобразования» существующих статических методов в методы расширения. Первый параметр статических методов в основном становится this. Например, это правильный Ломбок-расширенный код Java:

import lombok.experimental.ExtensionMethod; 

@ExtensionMethod({java.util.Arrays.class, Extensions.class}) 
public class ExtensionMethodExample { 
    public String test() { 
    int[] intArray = {5, 3, 8, 2}; 
    intArray.sort(); 

    String iAmNull = null; 
    return iAmNull.or("hELlO, WORlD!".toTitleCase()); 
    } 
} 

class Extensions { 
    public static <T> T or(T obj, T ifNull) { 
    return obj != null ? obj : ifNull; 
    } 

    public static String toTitleCase(String in) { 
    if (in.isEmpty()) return in; 
    return "" + Character.toTitleCase(in.charAt(0)) + 
     in.substring(1).toLowerCase(); 
    } 
} 

Обратите внимание, что методы расширения Ломбок могут быть «прибегли» на нуль объектов - до тех пор, как статический метод является нулевым безопасным, NullPointerException не будет сгенерировано , так как это в основном переведено на вызов статического метода. Да - это сводится к синтаксическому сахару, но я думаю, что это еще более читаемо, чем обычные вызовы статических методов.

Кроме того, вы можете использовать какой-либо другой язык JVM с совместимостью Java, если это нормально в вашем проекте. Например, Kotlin поставляется с extension methods functionality, а также некоторые полезные расширения, уже определенные в стандартной библиотеке. Вот Kotlin and Lombok comparison.

1

Decorator Pattern, возможно, самое близкое совпадение. Он использует интерфейс для поддержки совместимости и состава типа для улучшения существующей функции класса. Это не тот же принцип, что и тот, который вы описываете, но может служить той же цели.

2

Это может быть сделано на других языках для JVM, таких как Scala, Groovy или Closure.

Например, в Groovy:

List.metaClass.printSize = { 
    println delegate.size() 
} 

[1,2,3].printSize() //prints 3 

В Scala можно использовать implicit conversions:

class PrefixedString(val s: String) { 
    def prefix = "prefix_" + s 
} 

implicit def stringToString(s: String) = new PrefixedString(s) 

"foo".prefix // returns "prefix_foo" 

Пожалуйста, посмотрите на this article.

Важное замечание в том, что Groovy/Scala исходный код предназначенный для компиляции в байт-код Java, так что полученные классы могут использоваться в Java-коде.

+1

Кроме того, Ломбок делает какую-то магию внутри, но это _is_ Java, поэтому говорит, что его «невозможно» не совсем верно. – JustACluelessNewbie

+1

ОК, спасибо за замечания, я только что обновил свой awser. –

+0

Пример Scala, вероятно, должен использовать «неявный класс», который 'extends AnyVal' – Clashsoft

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