2016-08-10 3 views
6

Swift에서는 기존 클래스의 확장을 만들어 필요할 때마다 기존 클래스에 추가 기능을 추가 할 수 있습니다. 또한 기존 클래스의 서브 클래스를 작성하지 않아도됩니다.자바는 신속한 클래스 확장을 지원합니까?

자바에 비슷한 기능이 있는지 궁금한가요? 또는 기존 Java 클래스에 추가 메서드를 추가하는 유일한 방법은 기존 클래스의 하위 클래스를 만드는 것입니까?

+2

Java에 없습니다. 그러나 모든 사람들이 스칼라에서 그 말에 만족하지는 않습니다. 가독성, 유지 보수성을 저해 할 수 있기 때문입니다. 일반적으로 XxxUtils 또는 Xxx와 같은 함수를 사용하여 클래스를 만듭니다. 상속은 거기에 자신의 문제 (최종 클래스, 오래된 코드의 강제 obsoletess, 중앙 집중 = 단 하나의 확장 지점). –

답변

5

아니요, 바닐라 자바에는 확장 방법이 없습니다. 그러나 Lombok은 주석 및 바이트 코드 생성 덕분에 확장 메서드 구문을 비롯한 많은 유용한 기능을 추가합니다.

주석의 @ExtensionMethod 주석을 사용하여 기존 정적 메서드를 확장 메서드로 "변환"할 수 있습니다. 정적 메서드의 첫 번째 매개 변수는 기본적으로 this이됩니다. - 한 정적 메소드가 null - 안전으로, NullPointerException가 throw되지 않습니다 롬복 확장 메서드가 null 객체의 "호출"할 수 있다는

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(); 
    } 
} 

참고 : 예를 들어,이 유효한 롬복 강화 된 자바 코드 이것은 기본적으로 정적 메서드 호출로 변환되기 때문에. 예 - 구문 설탕에 설명되어 있지만 일반적인 정적 메서드 호출보다 읽기 쉽습니다.

이외에도 Java 상호 운용성이있는 다른 JVM 언어를 프로젝트에서 사용할 수 있습니다. 예를 들어, Kotlinextension methods functionality뿐 아니라 표준 라이브러리에서 이미 정의 된 몇 가지 유용한 확장 기능을 제공합니다. 여기에 Kotlin and Lombok comparison이 있습니다.

1

Decorator Pattern은 아마도 가장 일치합니다. 인터페이스를 사용하여 유형 호환성 및 구성을 유지하여 기존 클래스의 기능을 향상시킵니다. 설명하는 것과 동일한 원리는 아니지만 동일한 목적을 달성 할 수 있습니다.

2

Scala, Groovy 또는 Closure와 같은 JVM의 다른 언어로도 수행 할 수 있습니다. 그루비의 예를 들어

:

스칼라에서
List.metaClass.printSize = { 
    println delegate.size() 
} 

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

당신이 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.

중요 발언에 봐주십시오 그루비/스칼라 소스 코드가 있다는 것입니다 Java 바이트 코드로 컴파일되도록 만들어서 결과 클래스를 Java 코드에서 사용할 수 있습니다.

+1

게다가, 롬복은 내부적으로 어떤 마술을하지만 자바는 "불가능하다"는 것은 사실이 아니라고 말합니다. – JustACluelessNewbie

+1

알았어, 고마워, 방금 내 awser를 업데이 트했습니다. –

+0

스칼라 예제는'extends AnyVal'을 사용하는'암시 적 클래스 '를 사용해야합니다. – Clashsoft