In een van mijn interviews werd mij gevraagd het verschil uit te leggen tussen een Interface en een Abstracte klasse.
Hier's mijn antwoord:
Methoden van een Java interface zijn impliciet abstract en kunnen geen implementaties hebben. Een Java abstracte klasse kan instance methoden hebben die een standaard gedrag implementeren.
Variabelen die in een Java interface worden gedeclareerd zijn standaard definitief. Een abstracte klasse kan niet-definitieve variabelen bevatten.
Leden van een Java interface zijn standaard public. Een Java abstracte klasse kan de gebruikelijke smaken van klasse leden hebben zoals private, protected, enz.
Een Java interface moet geïmplementeerd worden met het keyword "implements"; Een Java abstracte klasse moet worden uitgebreid met het sleutelwoord "extends".
Een interface kan alleen een andere Java interface uitbreiden, een abstracte klasse kan een andere Java klasse uitbreiden en meerdere Java interfaces implementeren.
Een Java klasse kan meerdere interfaces implementeren maar kan slechts één abstracte klasse uitbreiden.
De interviewer was echter niet tevreden, en vertelde me dat deze beschrijving "boekkennis" vertegenwoordigde.
Hij vroeg me om een meer praktisch antwoord, en legde uit wanneer ik een abstracte klasse zou verkiezen boven een interface, aan de hand van praktische voorbeelden.
Waar ging ik in de fout?
Niets is perfect in deze wereld. Ze hadden misschien een meer praktische aanpak verwacht.
Maar na uw uitleg zou u deze regels kunnen toevoegen met een iets andere benadering.
Interfaces zijn regels (regels omdat je er een implementatie aan moet geven die je niet kunt negeren of vermijden, zodat ze als regels worden opgelegd) die werken als een gemeenschappelijk begripsdocument tussen verschillende teams in de softwareontwikkeling.
Interfaces geven het idee wat er gedaan moet worden, maar niet hoe het gedaan zal worden. Dus de uitvoering hangt volledig af van de ontwikkelaar door het volgen van de gegeven regels (dat wil zeggen gegeven handtekening van methoden).
Abstracte klassen kunnen abstracte declaraties, concrete implementaties, of beide bevatten.
Abstracte declaraties zijn als regels die gevolgd moeten worden en concrete implementaties zijn als richtlijnen (je kunt ze gebruiken zoals ze zijn of je kunt ze negeren door ze te overriden en er je eigen implementatie aan te geven).
Bovendien zijn methoden met dezelfde signatuur die het gedrag in verschillende contexten kunnen veranderen, voorzien als interfaceverklaringen als regels om dienovereenkomstig in verschillende contexten te implementeren.
Edit: Java 8 maakt het mogelijk om standaard en statische methodes in een interface te definiëren.
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
Wanneer een klasse nu SomeInterface implementeert, is het niet verplicht om de standaardmethoden van de interface te implementeren.
Als we een andere interface hebben met de volgende methodes:
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java staat het uitbreiden van meerdere klassen niet toe omdat dit resulteert in het "Diamond Probleem " waarbij de compiler niet in staat is om te beslissen welke methode van de superklasse moet worden gebruikt. Met de standaard methodes, zal het diamanten probleem zich ook voordoen voor interfaces. Want als een klasse zowel
SomeInterfaceOne and SomeInterfaceTwo
en niet de gemeenschappelijke standaard methode implementeert, kan de compiler niet beslissen welke te kiezen. Om dit probleem te vermijden, is het in java 8 verplicht om gemeenschappelijke standaardmethodes van verschillende interfaces te implementeren. Als een klasse beide bovenstaande interfaces implementeert, moet ze de defaultMethod() methode implementeren anders zal de compiler een fout genereren.
Je uitleg ziet er goed uit, maar misschien leek het alsof je het allemaal uit een leerboek las.
Waar ik me meer aan stoor is, hoe solide was je voorbeeld? Heb je de moeite genomen om bijna alle verschillen tussen abstract en interfaces op te nemen?
Persoonlijk zou ik deze link voorstellen: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
voor een uitputtende lijst van verschillen...
Ik hoop dat het u en alle andere lezers helpt bij hun toekomstige interviews
Een interface is een "contract" waarbij de klasse die het contract implementeert belooft om de methodes te implementeren. Een voorbeeld waar ik een interface moest schrijven in plaats van een klasse was toen ik een spel van 2D naar 3D aan het upgraden was. Ik moest een interface maken om klassen te delen tussen de 2D en de 3D versie van het spel.
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
Dan kan ik de methodes implementeren op basis van de omgeving, terwijl ik nog steeds in staat ben om die methodes aan te roepen vanuit een object dat'niet weet welke versie van het spel dat aan het laden is.
public class Adventure extends JFrame implements Playable
publieke class Dungeon3D extends SimpleApplication implements Playable
publieke klasse Main extends SimpleApplication implementeert AnimEventListener, ActieLuisteraar, Afspeelbaar
.
Typisch, in de spelwereld, kan de wereld een abstracte klasse zijn die methodes uitvoert op het spel:
public abstract class World...
public Playable owner;
public Playable getOwner() {
return owner;
}
public void setOwner(Playable owner) {
this.owner = owner;
}