[JAVA] Abstracte klasse + interface overerving

Pagina: 1
Acties:
  • 364 views sinds 30-01-2008
  • Reageer

  • Tuxie
  • Registratie: Augustus 2003
  • Laatst online: 21:43

Tuxie

En WeL nU!

Topicstarter
Het volgende 'rare' probleem overkwam mij:

Voor een schoolopdracht moet ik een klasse maken die een interface implementeert. Nu moet deze klasse die die interface implementeert abstract zijn. Dat kan dus, maar nu staat er letterlijk in de text dat specifiek 1 methode uit die interface ook abstract moet zijn en volgens mij kan dat niet. Ook de compiler gaat hierover zeuren......

Je krijgt dan dit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Interface SortedSet<Element> {
  public boolean lessThan();

  //nog veel meer methodes :)
}

public abstract class SortedList implements SortedSet {
  //methodes van de interface worden hier geimplementeerd

  //alleen nu moet de methode lessThan uit de interface abstract worden (staat in opgave)
  //IMHO kan dit niet :?
  public abstract boolean lessThan();
}


De compiler zeurt hier (uiteraard) over een name clash en dat het een het ander niet 'override'. Volgens mij kan deze constructie ook niet of doe ik hier wat fout?

Het probleem is dus dat ik een abstracte class maak die methodes uit de interface implementeert maar 1 methode uit die interface (in dit geval lessThan) wil ik de klasse uitwerken die onder de baseclass zit. (Dus die overerft van SortedList). Hoe bereik ik dit?

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

attamottamotta schreef op woensdag 19 oktober 2005 @ 22:08:
Het volgende 'rare' probleem overkwam mij:

Voor een schoolopdracht moet ik een klasse maken die een interface implementeert. Nu moet deze klasse die die interface implementeert abstract zijn. Dat kan dus, maar nu staat er letterlijk in de text dat specifiek 1 methode uit die interface ook abstract moet zijn en volgens mij kan dat niet.
Dat kan wel. Iedere methode van de interface die de abstracte class niet implementeerd, die is automatisch abstract. En of die methode nu uit de interface is gekomen, of een abstract methode is van je abstract class, dat maakt niet uit (abstract staat voor niet geimplementeerd).
Ook de compiler gaat hierover zeuren......

Je krijgt dan dit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Interface SortedSet<Element> {
  public boolean lessThan();

  //nog veel meer methodes :)
}

public abstract class SortedList implements SortedSet {
  //methodes van de interface worden hier geimplementeerd

  //alleen nu moet de methode lessThan uit de interface abstract worden (staat in opgave)
  //IMHO kan dit niet :?
  public abstract boolean lessThan();
}


De compiler zeurt hier (uiteraard) over een name clash en dat het een het ander niet 'override'. Volgens mij kan deze constructie ook niet of doe ik hier wat fout?
Je kunt dit probleem eenvoudig fixen door door die public abstract boolean lessThan() te verwijderen uit je abstract class. Waarom de compiler begint te klagen, begrijp ik ook niet helemaal.

[ Voor 7% gewijzigd door Alarmnummer op 19-10-2005 22:25 ]


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Ondanks dat ik nu voor jou je huiswerk zit te doen reageer ik toch maar, omdat je zo stellig beweert dat het niet kan.

1. Als je een abstract klasse een interface laat implementeren dan worden automagisch alle methodes die je niet implementeert toegevoegd als abstracte methodes.

2. Als je het zelf doet dan is het gewoon dubbel, maar de compiler vindt dat prima:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Foo { 
    public void bar();
}

abstract class BlaBase implements Foo {
    
    // je mag dit erbij typen, of gewoon weglaten
    public abstract void bar();
}

class BlaImpl extends BlaBase {

    public void bar() {
        // Deze klasse moet altijd bar() implementeren      
    }   
}


Spuit elf na de reactie van alarmnummer, maar hopelijk is het nu duidelijk ;)

[ Voor 6% gewijzigd door misfire op 19-10-2005 22:25 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Precies. Ik kan me niet voorstellen dat de compiler erover begint te klagen dat je zowel een abstract methode van de abstract class hebt, als een van de interface.

Verwijderd

attamottamotta schreef op woensdag 19 oktober 2005 @ 22:08:
De compiler zeurt hier (uiteraard) over een name clash en dat het een het ander niet 'override'. Volgens mij kan deze constructie ook niet of doe ik hier wat fout?

Het probleem is dus dat ik een abstracte class maak die methodes uit de interface implementeert maar 1 methode uit die interface (in dit geval lessThan) wil ik de klasse uitwerken die onder de baseclass zit. (Dus die overerft van SortedList). Hoe bereik ik dit?
Je erft de methode lessThan() uit de interface. De compiler geeft die foutmelding omdat er, als je zelf ook nog de methode lessThan() als abstract gaat definieeren in de abstracte class, in feite twee methodes met dezelfde signature definieert in de abstracte class:

1. lessThan() uit de interface
2. lessThan() in de abstracte class zelf

Aangezien je niet twee methodes kunt definieeren met dezelde signature op hetzelfde niveau (lees hier: abstracte class) klaagt de compiler.


Je kunt idd gewoon in je abstracte class een method uit een interface die je implementeert overkrabben :-)

[ Voor 7% gewijzigd door Verwijderd op 20-10-2005 09:32 ]


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:03
Alarmnummer schreef op woensdag 19 oktober 2005 @ 22:18:
[...]

Dat kan wel. Iedere methode van de interface die de abstracte class niet implementeerd, die is automatisch abstract. En of die methode nu uit de interface is gekomen, of een abstract methode is van je abstract class, dat maakt niet uit (abstract staat voor niet geimplementeerd).


[...]

Je kunt dit probleem eenvoudig fixen door door die public abstract boolean lessThan() te verwijderen uit je abstract class. Waarom de compiler begint te klagen, begrijp ik ook niet helemaal.
Als ik het goed begrijp moet je dus in dit geval -als je die method als abstract wil hebben in je abstracte class-, die method gewoon niet opnemen in je abstracte class ?
Dat vind ik een beetje raar. Ugly zelfs.

Dan is het in C# imho toch wel wat netter opgelost. Daar kan je -moet je zelfs geloof ik- alle members van de interface definieren in de class die de interface implementeert. In dit geval zou je dus gewoon het abstract keyword aan die method moeten toevoegen. Ik geloof zelfs dat C# zou klagen als je het op de java-manier oplost. ff test...

Ja dus. :P
misfire:
Ondanks dat ik nu voor jou je huiswerk zit te doen reageer ik toch maar, omdat je zo stellig beweert dat het niet kan.
Huiswerkvragen zijn niet verboden hoor. ;)

[ Voor 9% gewijzigd door whoami op 20-10-2005 09:35 ]

https://fgheysels.github.io/


Verwijderd

Just a thought; controleer je imports is?

  • JaWi
  • Registratie: Maart 2003
  • Laatst online: 14-01 21:58

JaWi

maak het maar stuk hoor...

Laat me raden; je gebruikt JDK 5.0 en hebt je lessThan() methode niet ge-annoteerd met @Override. Dan begint de compiler idd over een name-clash te zeuren. Oplossing: zet in je abstracte klasse boven
je lessThan() method "@Override" en probeer het zaakje opnieuw te compileren...

Statistics are like bikinis. What they reveal is suggestive, but what they hide is vital.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
JaWi schreef op donderdag 20 oktober 2005 @ 09:44:
Laat me raden; je gebruikt JDK 5.0 en hebt je lessThan() methode niet ge-annoteerd met @Override. Dan begint de compiler idd over een name-clash te zeuren. Oplossing: zet in je abstracte klasse boven
je lessThan() method "@Override" en probeer het zaakje opnieuw te compileren...
De @Override is alleen informatief in 5.0: het is niet verplicht om @Override als annotatie op te nemen. De compiler checkt alleen of je ook daadwerkelijk iets override als je een @Override opneemt. Het is dus, itt C#, niet verplicht om override op te geven.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 25-04 12:33

Eelke Spaak

- Vlad -

whoami schreef op donderdag 20 oktober 2005 @ 09:33:
[...]


Als ik het goed begrijp moet je dus in dit geval -als je die method als abstract wil hebben in je abstracte class-, die method gewoon niet opnemen in je abstracte class ?
Dat vind ik een beetje raar. Ugly zelfs.
Je begrijpt het niet goed ;) .

Je mag de methodes uit een geïmplementeerde interface weglaten in een abstracte klasse, dan worden ze automatisch gemarkeerd als abstract. Dit hoeft echter niet; je mag ze ook gewoon noemen en voorzien van het keyword 'abstract'. Dit laatste vind ik ook een betere methode.

TheStreme - Share anything with anyone


  • JaWi
  • Registratie: Maart 2003
  • Laatst online: 14-01 21:58

JaWi

maak het maar stuk hoor...

mbravenboer schreef op donderdag 20 oktober 2005 @ 09:56:
[...]
De @Override is alleen informatief in 5.0: het is niet verplicht om @Override als annotatie op te nemen. De compiler checkt alleen of je ook daadwerkelijk iets override als je een @Override opneemt. Het is dus, itt C#, niet verplicht om override op te geven.
Strict genomen heb je helemaal gelijk, maar je kunt de compiler vertellen dat het afwezig zijn van de @Override-annotatie als error beschouwd moet worden (zoals bijv. in Eclipse). Mijn vermoeden is dat de TS dit als zodanig ook heeft ingesteld (of dat de IDE dit als zodanig ingesteld heeft)...

offtopic:
Wanneer komt er een nieuw artikeltje op je blog? Ik lees ze altijd met veel plezier :)

Statistics are like bikinis. What they reveal is suggestive, but what they hide is vital.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Precies.
Dit laatste vind ik ook een betere methode.
Ik vind het niet zo veel toevoegen. Je krijgt al een compiletime melding als je het vergeet te implementeren bij de eind class. En abstracte classes horen geen contract te definieeren (althans.. niet voor de buitenwereld) en zijn daarom vaak niets anders dan convenience structuren.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 20:42

Robtimus

me Robtimus no like you

attamottamotta schreef op woensdag 19 oktober 2005 @ 22:08:
Java:
1
2
3
4
5
interface SortedSet<Element> {
}

public abstract class SortedList implements SortedSet {
}
En wat gebeurt er als je die class signature verandert in het volgende:
Java:
1
2
public abstract class SortedList<Element> implements SortedSet<Element> {
}
?

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Tuxie
  • Registratie: Augustus 2003
  • Laatst online: 21:43

Tuxie

En WeL nU!

Topicstarter
Ha, dank voor de reacties.

Ik gebruik iid JDK 5.0 i.c.m. die nieuwe <Elem> toevoegingen. Ik ga straks nog even kijken waarom hij idd precies die melding gaf, nu ik weet dat het wel moet kunnen.

Overigens is dit niet mijn huiswerkopdracht maar die van iemand anders O-)

Verwijderd

Eelke Spaak schreef op donderdag 20 oktober 2005 @ 09:56:
[...]

Je begrijpt het niet goed ;) .

Je mag de methodes uit een geïmplementeerde interface weglaten in een abstracte klasse, dan worden ze automatisch gemarkeerd als abstract.
Ik ben er niet helemaal zeker van dat "automatisch gemarkeerd als abstract" het gebeuren goed uitlegd (ik denk dat je wel hetzelfde bedoeld).

Het is namelijk zo dat een method gedeclareerd in een interface standaard public en abstract is. Dit zijn de default modifiers, je kunt ze beide weglaten en de semantiek is dan precies hetzelfde. Vervolgens hoeft een abstracte classe niet elke method te implementeren. Of er nu sprake is van een abstracte method uit een interface of een parent abstrate classe maakt niets uit. Elke child class kan 0, 1 of meerdere methods een implementatie geven. Is er voor alle methods een definitie aanwezig, dan is de class niet meer abstract en kan een instantie gemaakt worden.

Het is dus niet het geval dat de compiler of preprocessor or whatever, een method met abstract ervoor achter de schermen gaat toevoegen in de situate van de TS. Ook komt er in die situatie niet automatisch een abstract modifier op de method, die zat er namelijk al op toen je hem in de interface declareerde.

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 20:42

Robtimus

me Robtimus no like you

Verwijderd schreef op donderdag 20 oktober 2005 @ 21:05:
Is er voor alle methods een definitie aanwezig, dan is de class niet meer abstract en kan een instantie gemaakt worden.
Heel mooi verhaal, met 1 foutje: je kan ook abstract classes hebben zonder abstract methods, zolang de class maar de abstract modifier heeft. En dan, ondanks dat alle methods geimplementeerd zijn, kun je nog steeds geen instantie aanmaken.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

IceManX schreef op donderdag 20 oktober 2005 @ 22:02:
[...]
Heel mooi verhaal, met 1 foutje: je kan ook abstract classes hebben zonder abstract methods, zolang de class maar de abstract modifier heeft. En dan, ondanks dat alle methods geimplementeerd zijn, kun je nog steeds geen instantie aanmaken.
Natuurlijk waar :) Goede aanvulling!

edit:

Maar om dan nog even een situatie aan te geven waarin je ondanks ontbreken van abstract modifier en aanwezigheid van alle implementaties nog steeds geen instantie kunt maken is natuurlijk met een non-public contructor.

[ Voor 24% gewijzigd door Verwijderd op 20-10-2005 23:16 ]


  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 25-04 12:33

Eelke Spaak

- Vlad -

Verwijderd schreef op donderdag 20 oktober 2005 @ 21:05:
[...]


Ik ben er niet helemaal zeker van dat "automatisch gemarkeerd als abstract" het gebeuren goed uitlegd (ik denk dat je wel hetzelfde bedoeld).
Yup, ik bedoelde hetzelfde, zij het dat ik het niet in de details had kunnen vertellen zoals jij deed :) .

TheStreme - Share anything with anyone

Pagina: 1