2014-10-14 18 views
10

Domyślnie każda klasa Groovy ma konstruktor Map, np.Dodawanie niestandardowego konstruktora bez utraty domyślnego konstruktora map

class Foo { 
    def a 
    def b 
} 

// this works 
new Foo(a: '1', b: '2') 

Jednak wydaje się, że tak szybko, jak dodać konstruktora z własną rękę, to konstruktor domyślny nie jest dostępny

class Foo { 

    Foo(Integer x) { 
    println 'my constructor was called' 
    } 

    def a 
    def b 
} 

// this works 
new Foo(1) 

// now this doesn't work, I get the error: groovy.lang.GroovyRuntimeException: 
// failed to invoke constructor 
new Foo(a: '1', b: '2') 

Czy jest możliwe aby dodać własny konstruktor bez utraty domyślną mapę konstruktor? Próbowałem opisywanie klasy z @TupleConstructor, ale to nie miało znaczenia. Rozumiem, że mogę samodzielnie dodać konstruktora mapy, np.

public Foo(Map map) {  
    map?.each { k, v -> this[k] = v } 
} 

Choć konstruktor powyżej nie jest identyczny do konstruktora domyślnego mapy ponieważ kluczowym na mapie, że nie ma odpowiedniego obiektu klasy spowoduje wyjątek.

Odpowiedz

18

Możesz użyć adnotacji @InheritConstructors.

@groovy.transform.InheritConstructors 
class Foo { 
    def a, b 
    Foo(Integer x) { 
     println 'my constructor was called' 
    } 
} 

// this works 
new Foo(1) 

def mappedFoo = new Foo(a: '1', b: '1') 
assert mappedFoo.a == '1' 
assert mappedFoo.b == '1' 
+0

To prawdopodobnie czystsze opcja. –

+0

Zdarzyło się to, ponieważ 'Foo' dziedziczy domyślny konstruktor no-arg z podstawowej klasy' Object'. Przerywa, jeśli klasa bazowa nie ma konstruktora no-arg, i będzie zanieczyszczać przestrzeń konstruktora, jeśli klasa bazowa ma przeciążone wiele konstruktorów. @ Odpowiedź Willa jest właściwą drogą. –

4

Dodaj no-Arg konstruktor i nazywają super np

class Foo { 
    Foo(Integer x) { 
    println 'my constructor was called' 
    } 

    Foo() { super() } // Or just Foo() {} 

    def a 
    def b 
} 

f = new Foo(a: '1', b: '2') 
println f.a 
=> 1