[Java] generics, overloading methods van een typed class.

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
Ok, ik snap iets niet en krijg het ook maar niet werkend. Ik heb de volgende code:

Java:
1
2
3
4
public interface SqlMetaData<T>
{
    void convert(ResultSet rs, T a) throws SQLException;
}


Java:
1
2
3
4
5
6
7
8
public class AccountSqlMetaData implements SqlMetaData<Account>
{
    public void convert(ResultSet rs, Account account) throws SQLException
    {
        account.setFoo(rs.getInt(getColumnName(FOO)));
        //...etc
    }
}


Java:
1
2
3
4
5
6
7
8
public class CustomerSqlMetaData extends AccountSqlMetaData
{
    public void convert(ResultSet rs, Customer customer) throws SQLException
    {
        super.convert(rs, customer);
        customer.setBar.getString(getColumnName(BAR)));
        //...etc
    }


Clientcode:
Java:
1
2
3
SqlMetaData smd = new CustomerSqlMetaData();
Customer c = new Customer();
smd.convert(rs, c);


Dit systeem is (zoals je al verwachtte) een manier om een resultset om te zetten in het echt object. Nu had ik bedacht dat aangezien Customer overerft van Account (en ook in dezelfde tabel staat) ik de AccountSqlMetaData ook kon overerven en dat, wanneer de convert(ResultSet rs, T t) methode wordt afgeroepen, deze van CustomerSqlMetaData zou zijn. Helaas wordt alleen de convert methode van AccountSqlMetaData afgeroepen :? setBar() wordt dus nooit uitgevoerd.

Misschien dat ik iets vreselijks fout doe, maar zie het eventjes niet.

Update:
Ik zie inmiddels wel waar ik een redelijk grove denkfout maak. De convert method in CustomerSqlMetaData overwrite natuurlijk niet de convert method in AccountSqlMetaData 8)7

[ Voor 6% gewijzigd door Standeman op 07-01-2010 15:46 ]

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Foo{}
class Bar extends Foo{}

interface Dao<T> {
  void get(T param);
}

class FooDAO implements Dao<Foo> {

  @Override
  public void get(Foo param) {

  }
}

class BarDAO extends FooDAO{

  @Override
  public void get(Bar param) { //Compiler error, dit is geen override
    super.get(param);
  }
  
}


Hierbij komt er inderdaad een compilererror op de overriden methode in BarDAO. Ik weet ook even zo niet hoe je dit kan op lossen.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
Nick_S schreef op donderdag 07 januari 2010 @ 15:45:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Foo{}
class Bar extends Foo{}

interface Dao<T> {
  void get(T param);
}

class FooDAO implements Dao<Foo> {

  @Override
  public void get(Foo param) {

  }
}

class BarDAO extends FooDAO{

  @Override
  public void get(Bar param) { //Compiler error, dit is geen override
    super.get(param);
  }
  
}


Hierbij komt er inderdaad een compilererror op de overriden methode in BarDAO. Ik weet ook even zo niet hoe je dit kan op lossen.
Tja, daar zit ik nu ook even over na te denken. Mijn "bug" is nu wel helder, maar ik heb nog geen idee hoe ik het op ga lossen. Even verder puzzelen dus.

Het onderstaande werkt ovierigens wel.. Maar het is zo ranzig als de pest :)
Java:
1
2
3
4
5
6
7
8
9
class BarDAO extends FooDAO{

  @Override
  public void get(Foo param) { //Compiler error, dit is geen override
    Bar bar = (Bar) param;
    super.get(bar);
  }
  
}

[ Voor 15% gewijzigd door Standeman op 07-01-2010 15:50 ]

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Vandaar dat de @Override annotatie best handig is. ;)

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 05:18
Het probleem is dat CustomerSqlMetaData alleen SqlMetaData<Account> implementeert (indirect, via AccountSqlMetaData) en niet SqlMetaData<Customer>. De methode die je gedeclareert hebt voor CustomerSqlMetaData is géén overload (zoals je waarschijnlijk wilde) want hij verschilt in argumenttype van convert(ResultSet, Account) (gedeclareerd in AccountSqlMetaData) en van convert(ResultSet,Object) (impliciet gedeclareerd in SqlMetaData).

Wanneer je dus in de client code convert() aanroept, roep je de methode convert(ResultSet,Object)[ impliciet gedefinieerd in AccountSqlMetaData aan, en die roept dan convert(ResultSet, Account) aan.

Je moet er dus voor zorgen dat die convert(ResultSet,Object)[ methode óók in CustomerSqlMetaData overridden wordt. Hoe je dat voor elkaar krijgt weet ik eigenlijk niet precies...

edit:
laat :O

Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
Ik ben tot deze over ervings oplossing trouwens gekomen omdat ik zin had om allerlei metadata info te kopieren en op deze manier er makkelijk vanaf te zijn. Gaat dus niet lukken, want ik kan bij CustomerSqlMetaData ook geen andere type aangeven.

Misschien een goede reden om het te splitsen in twee classes. De metadata en de conversie van resultset naar object. Het aanbieden van metadata en het converteren van een resultset zijn toch twee verschillende verantwoordelijkheden / taken, dus zo raar is het niet om het op te splitsen.

[ Voor 19% gewijzigd door Standeman op 07-01-2010 16:05 ]

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 18-09 22:40

Nick_S

++?????++ Out of Cheese Error

Standeman schreef op donderdag 07 januari 2010 @ 15:47:
[...]

Tja, daar zit ik nu ook even over na te denken. Mijn "bug" is nu wel helder, maar ik heb nog geen idee hoe ik het op ga lossen. Even verder puzzelen dus.

Het onderstaande werkt ovierigens wel.. Maar het is zo ranzig als de pest :)
Java:
1
2
3
4
5
6
7
8
9
class BarDAO extends FooDAO{

  @Override
  public void get(Foo param) { //Compiler error, dit is geen override
    Bar bar = (Bar) param;
    super.get(bar);
  }
  
}
Je gaat het alleen nooit anders voor elkaar krijgen.

Java:
1
2
3
Foo foo = ...
FooDao fooDao = new BarDao();
fooDao.get(foo);


Dit is in principe correcte code, alleen de BarDao kan niet met Foo overweg. :( Problemen!

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Dit is de manier om het te doen met generics:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AccountSqlMetaData<T extends Account> implements SqlMetaData<T>
{
    public void convert(ResultSet rs, T account) throws SQLException
    {
        account.setFoo(rs.getInt(getColumnName(FOO)));
        //...etc
    }
}
public class CustomerSqlMetaData extends AccountSqlMetaData<Customer>
{
    public void convert(ResultSet rs, Customer customer) throws SQLException
    {
        super.convert(rs, customer);
        customer.setBar.getString(getColumnName(BAR)));
        //...etc
    }
}

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
Macros schreef op donderdag 07 januari 2010 @ 20:19:
Dit is de manier om het te doen met generics:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AccountSqlMetaData<T extends Account> implements SqlMetaData<T>
{
    public void convert(ResultSet rs, T account) throws SQLException
    {
        account.setFoo(rs.getInt(getColumnName(FOO)));
        //...etc
    }
}
public class CustomerSqlMetaData extends AccountSqlMetaData<Customer>
{
    public void convert(ResultSet rs, Customer customer) throws SQLException
    {
        super.convert(rs, customer);
        customer.setBar.getString(getColumnName(BAR)));
        //...etc
    }
}
:| :o Jaaaa.. tuurlijk.. Het kwartje valt nu eindelijk. Behoorlijk logisch zoals ik het nu zie. :) Thanks!

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Macros schreef op donderdag 07 januari 2010 @ 20:19:
Dit is de manier om het te doen met generics:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AccountSqlMetaData<T extends Account> implements SqlMetaData<T>
{
    public void convert(ResultSet rs, T account) throws SQLException
    {
        account.setFoo(rs.getInt(getColumnName(FOO)));
        //...etc
    }
}
public class CustomerSqlMetaData extends AccountSqlMetaData<Customer>
{
    public void convert(ResultSet rs, Customer customer) throws SQLException
    {
        super.convert(rs, customer);
        customer.setBar.getString(getColumnName(BAR)));
        //...etc
    }
}
Met de aantekening dat je hiermee niet gewoon

Java:
1
new AccountSqlMetaData()
kunt doen. Om AccountSqlMetaData te initialiseren, moet je óf een type parameter meegeven (new AccountSqlMetaData<Account>()), óf een niet-generic subclass maken (met niks erin)

Java:
1
2
3
public class AccountSqlMetaDataImpl extends AccountSqlMetaData<Account> {
// leeg
}

Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
YopY schreef op vrijdag 08 januari 2010 @ 09:29:
[...]


Met de aantekening dat je hiermee niet gewoon

Java:
1
new AccountSqlMetaData()
kunt doen. Om AccountSqlMetaData te initialiseren, moet je óf een type parameter meegeven (new AccountSqlMetaData<Account>()), óf een niet-generic subclass maken (met niks erin)

Java:
1
2
3
public class AccountSqlMetaDataImpl extends AccountSqlMetaData<Account> {
// leeg
}
Daar was ik inmiddels ook al achter gekomen. Ik heb nog een andere method in AccountSqlMetaData zitten, namelijk:
Java:
1
2
3
4
5
6
    public T convert(ResultSet rs) throws SQLException
    {
        Account account = new Account();
        convert(rs, account);
        return account;
    } 


Deze werkt dan niet meer. Ik denk dat ik 'm dan toch ga subclassen. 1 voor account en 1 voor customer met een gezamenlijke abstracte superclass.

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Wat is mis met:
Java:
1
2
3
4
public interface SqlMetaData<T>
{
    void convert(ResultSet rs, T a) throws SQLException;
}


Java:
1
2
3
4
5
6
7
8
public class AccountSqlMetaData implements SqlMetaData<Account>
{
    public void convert(ResultSet rs, Account account) throws SQLException
    {
        account.setFoo(rs.getInt(getColumnName(FOO)));
        //...etc
    }
}


Bemerk de extra implements:
Java:
1
2
3
4
5
6
7
8
public class CustomerSqlMetaData extends AccountSqlMetaData implements SqlMetaData<Customer>
{
    public void convert(ResultSet rs, Customer customer) throws SQLException
    {
        super.convert(rs, (Account)customer);
        customer.setBar.getString(getColumnName(BAR)));
        //...etc
    }


Dan krijg je overloading ipv overriding...

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 15-05 16:29

Macros

I'm watching...

Wat Highguy zegt is ook een goede oplossing!

"Beauty is the ultimate defence against complexity." David Gelernter


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
Macros schreef op zaterdag 09 januari 2010 @ 11:38:
Wat Highguy zegt is ook een goede oplossing!
Maar geeft wel een compiler error ;)

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Dewelke ?

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:15

Janoz

Moderator Devschuur®

!litemod

Waarschijnlijk iets met haakje en puntje oid

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
SqlMetaData cannot be inherited with different arguments: <Customer> and <Account>

[ Voor 21% gewijzigd door Standeman op 12-01-2010 13:52 ]

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Kun je overstappen naar C#, die kan dit soort dingen wel >:)

Ik ben normaal niet bezig in Java, dus ik zal je moeten overlaten aan de gratie van de aanwezige Java guru's.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
H!GHGuY schreef op woensdag 13 januari 2010 @ 12:54:
Kun je overstappen naar C#, die kan dit soort dingen wel >:)
ik heb ongeveer 5 jaar geleden met VS (+ C#) gewerkt en vond het echt een heeel groot drama!! Sindsdien raak ik het met geen stok meer aan :P
(ik hoop dat MS inmiddels wel snapt dat refactoring functies handig zijn).
Ik ben normaal niet bezig in Java, dus ik zal je moeten overlaten aan de gratie van de aanwezige Java guru's.
Ik heb het al werkend door een abstracte class de definieren en twee subclasses te schrijven. :)

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Standeman schreef op woensdag 13 januari 2010 @ 13:02:
[...]
ik heb ongeveer 5 jaar geleden met VS (+ C#) gewerkt en vond het echt een heeel groot drama!! Sindsdien raak ik het met geen stok meer aan :P
(ik hoop dat MS inmiddels wel snapt dat refactoring functies handig zijn).
Note: Generics in C# en Java zijn heel verschillend. Op het allerhoogste niveau lijken ze op elkaar (ze dienen hetzelfde doel), maar er zijn een paar hele belangrijke verschillende designkeuzes gemaakt.

Hier wordt het naar mijn idee vrij goed uitgelegd. http://stackoverflow.com/...3/differences-in-generics (het performance argument is naar mijn idee bullshit, maar verder klopt het m.i. prima).
[...]
Ik heb het al werkend door een abstracte class de definieren en twee subclasses te schrijven. :)
Die abstracte class kun je misschien wel generic implementeren... Dan heb je volgens mij nog steeds een nette oplossing.

Fat Pizza's pizza, they are big and they are cheezy


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Standeman schreef op woensdag 13 januari 2010 @ 13:02:
[...]

ik heb ongeveer 5 jaar geleden met VS (+ C#) gewerkt en vond het echt een heeel groot drama!! Sindsdien raak ik het met geen stok meer aan :P
(ik hoop dat MS inmiddels wel snapt dat refactoring functies handig zijn).
Ik heb de omgekeerde ervaring van tijdens mijn tijd op de lesbanken. C# in VS werkt lekker, maar Java kijk ik liever niet meer naar. Het was wel nog net voor het generics tijdperk.

De gustibus et coloribus...

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19-09 21:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

JKVA schreef op woensdag 13 januari 2010 @ 21:32:
Hier wordt het naar mijn idee vrij goed uitgelegd. http://stackoverflow.com/...3/differences-in-generics (het performance argument is naar mijn idee bullshit, maar verder klopt het m.i. prima).
Mja, het C++ verhaal is een beetje slap gelul. Het feit dat het meestal naar machinecode compileert heeft er geen reet mee te maken. C++/CLI produceert gewoon .Net IL, en daarmee kun je óók templates gebruiken. Het verschil is dat bij templates de semantische analyse pas plaatsvindt bij template instantiatie, dus als T bekend is. Generics (zowel in Java als in C#) werken daarentegen altijd hetzelfde ongeacht T, aan de hand van de constraints op T.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
H!GHGuY schreef op donderdag 14 januari 2010 @ 12:51:
[...]

Ik heb de omgekeerde ervaring van tijdens mijn tijd op de lesbanken. C# in VS werkt lekker, maar Java kijk ik liever niet meer naar. Het was wel nog net voor het generics tijdperk.

De gustibus et coloribus...
Het is maar idd maar net wat je comfortzone is plus dat de beschikbare IDE's voor java jaren geleden meer functionaliteit hadden dan VS. Zover ik heb begrepen doet VS absoluut niet meer onder voor de populaire java IDE's. :)

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 05:18
Standeman schreef op donderdag 14 januari 2010 @ 14:18:
[..] de beschikbare IDE's voor java [hadden] jaren geleden meer functionaliteit dan VS. Zover ik heb begrepen doet VS absoluut niet meer onder voor de populaire java IDE's. :)
Wellicht heb jij het over een andere periode dan ik, maar toen ik kennismaakte met Java (in het jaar '00) was er juist geen fatsoenlijke IDE. Ja, we konden met JBuilder werken: een IDE geschreven in Java met AWT, draaiende in een VM zonder JIT: traag als stront door een trechter, zo stabiel als de Toren van Pisa. In die tijd was Visual Studio 6 ook uit, en die draaide juist razendsnel en retestabiel.

Ik denk dat Java een groot deel van z'n slechte imago te danken heeft uit de waardeloze development tools uit de vroege dagen. In die dagen codede ik liever in een text editor met een console om de compiler aan te roepen, dan met een IDE. Dat veranderde pas toen Eclipse beschikbaar kwam, waarin AWT en Swing naar de prullenbak verwezen werden ten faveure van een semi-native widget set (SWT).

Waarschijnlijk doel je op een ander tijdvak, maar het sentiment dat Java traditioneel goede tool support heeft, deel ik absoluut niet. ;)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 10:15

Janoz

Moderator Devschuur®

!litemod

Euhm... IntelliJ IDEA van Jetbrains? Voor zover ik terug kan vinden waren ze in december 2001 al bij versie 2.5. Ik ben niet verbaasd wanneer blijkt dat IDEA 3 (uit 2002/2003) meer functionaliteiten en productiviteit biedt dan VS 2006 of zelfs VS 2008.

Uiteindelijk vonden ze het zo sneu dat MS de .NETers zo in de kou liet staan met gebrekkige functionaliteit dat ze zelf maar met ReSharper gekomen zijn :+ :P..

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Standeman
  • Registratie: November 2000
  • Nu online

Standeman

Prutser 1e klasse

Topicstarter
Ik ben ongeveer in 2002 serieus met Java (JBuilder, daarna Netbeans 4) aan de slag gegaan en in 2004 ging mijn toenmalige werkgever over van java naar .NET. Dat was wel even "wennen" zeg maar. Dus het was inderdaad net een ander tijdsvak.

The ships hung in the sky in much the same way that bricks don’t.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 05:18
Janoz schreef op donderdag 14 januari 2010 @ 16:50:
Euhm... IntelliJ IDEA van Jetbrains? Voor zover ik terug kan vinden waren ze in december 2001 al bij versie 2.5.
Volgens Wikipedia: The first version of IntelliJ IDEA appeared in January 2001 dus die was er toen nog niet. Sowieso waren IDEs toen ook nog extra traag omdat de JIT compiler nog niet echt geniaal was, en AWT zoals genoemd ook niet snel is.
Pagina: 1