Cum ar trebui să am explicat diferenta intre o Interfata si o clasa Abstracta?

În unul dintre interviurile mele, am fost rugat să explice diferența dintre o Interfata si un Abstract class.

Aici's răspunsul meu:

Metode de Java interface sunt implicit abstracte și nu pot avea implementări. Un Java clasă abstractă poate avea exemplu metode care implementează un comportament implicit.

Variabilele declarate într-o interfață Java sunt în mod implicit la final. O clasă abstractă poate conține non-variabile finale.

Membrii unei interfețe Java sunt publice în mod implicit. Un abstract Java clasa poate avea de obicei arome de membrii clasei ca privat, protejate, etc.

Java interface ar trebui să fie implementate folosind cuvântul cheie "implementează"; O Java clasă abstractă ar trebui să fie extins folosind cuvântul cheie "extends".

O interfață poate extinde un alt Java interface numai, o clasă abstractă se poate extinde o altă clasă Java și implementa mai multe interfețe Java.

O clasă Java poate implementa mai multe interfețe, dar se poate extinde numai o clasă abstractă.

Cu toate acestea, intervievatorul nu a fost mulțumit, și mi-a spus că această descriere a reprezentat "cunoaștere livrescă".

Mi-a cerut o mai practic de răspuns, explicând când aș alege o clasă abstractă pe o interfață, folosind exemple practice.

Unde am greșit?

Comentarii la întrebare (14)

Am să vă dau un exemplu:

public interface LoginAuth{
   public String encryptPassword(String pass);
   public void checkDBforUser();
}

Acum sa presupunem ca ai 3 baze de date în aplicația dumneavoastră. Apoi, fiecare și fiecare aplicare pentru care baza de date trebuie să definiți mai sus 2 metode:

public class DBMySQL implements LoginAuth{
          // Needs to implement both methods
}
public class DBOracle implements LoginAuth{
          // Needs to implement both methods
}
public class DBAbc implements LoginAuth{
          // Needs to implement both methods
}

Dar ce se întâmplă dacă encryptPassword() nu este baza de date dependente, și-l's la fel pentru fiecare clasă? Atunci cele de mai sus nu ar fi o abordare bună.

În schimb, ia în considerare această abordare:

public abstract class LoginAuth{
   public String encryptPassword(String pass){
            // Implement the same default behavior here 
            // that is shared by all subclasses.
   }

   // Each subclass needs to provide their own implementation of this only:
   public abstract void checkDBforUser();
}

Acum, în fiecare copil de clasa, avem nevoie doar de a pune în aplicare o metodă - metoda care este baza de date dependente.

Am încercat meu cel mai bun și Sper că acest lucru va șterge îndoieli.

Comentarii (12)

Nimic nu este perfect în această lume. Ei ar fi putut aștepta mai mult de o abordare practică.

Dar, după explicația ta ai putea adăuga aceste linii cu o abordare ușor diferită.

  1. Interfețele sunt norme (reguli pentru că trebuie să dea o punere în aplicare pentru a le că poți't ignora sau evita, astfel încât acestea sunt impuse ca reguli), care funcționează ca o înțelegere comună document între diferite echipe în dezvoltarea de software.

  2. Interfețe da o idee despre ce este de făcut, dar nu cum se va face. Astfel punerea în aplicare complet depinde de producător, urmând regulile date (mijloace dat semnatura de metode).

  3. Clasele abstracte pot contine abstract declarații, beton implementări, sau ambele.

  4. Rezumat declarațiile sunt ca regulile să fie respectate și beton implementări sunt ca orientări (puteți folosi așa cum este sau se poate ignora prin imperative și oferindu-ta implementarea la ea).

  5. Mai mult decât atât ce metode cu aceeași semnătură poate schimba comportamentul în diferite context sunt furnizate ca interfață declarații ca regulile să pună în aplicare în mod corespunzător în diferite contexte.

Edit: Java 8 facilitează pentru a defini implicit și metode statice în interfață.

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

Acum, când o clasă va pune în aplicare SomeInterface, nu este obligatoriu să se prevadă punerea în aplicare implicit pentru metodele din interfață.

Dacă avem o altă interfață cu următoarele metode:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

Java nu permite extinderea mai multe clase, deoarece aceasta rezultă din "Diamant Problemă" în cazul în care compilatorul nu poate decide care superclasa metodă de a utiliza. Cu metodele implicite, diamantul problema va apărea pentru interfețele de asemenea. Pentru că dacă o clasă este atât de punere în aplicare

SomeInterfaceOne and SomeInterfaceTwo

și nu pună în aplicare politica metoda implicită, compilatorul nu poate decide care unul a alege. Pentru a evita această problemă, în java 8 este obligatoriu să pună în aplicare frecvente default metode de interfețe diferite. Dacă orice clasă este de punere în aplicare ambele interfețe de mai sus, trebuie să furnizeze o implementare pentru defaultMethod() metoda în caz contrar compilatorul va arunca compilare eroare.

Comentarii (6)

Ai facut un rezumat bun practice diferențe în utilizarea și punerea în aplicare, dar nu a spus nimic despre diferența de sens.

O interfata este o descriere a comportamentului de punere în aplicare clasă va avea. De punere în aplicare clasă asigură, pe care-l vor avea aceste metode care pot fi utilizate pe ea. Acesta este de fapt un contract sau o promisiune clasa are de a face.

O abstract class este o bază pentru diferite subclase care împărtășesc un comportament care nu are nevoie să fie creat în mod repetat. Subclasele trebuie să completeze comportamentul și au opțiunea de a suprascrie predefinite comportament (atâta timp cât acesta nu este definit ca "finală" sau "privat").

Veți găsi exemple bune în java.util pachet care include interfețe astfel de "Listă" și clase abstracte ca AbstractList care deja implementeaza interfata. De [documentația oficială][1] descrieAbstractList`, după cum urmează:

Această clasă oferă un scheletului punerea în aplicare a Listei de interfață pentru a minimiza efortul necesar pentru a pune în aplicare această interfață susținută de o "acces aleator" depozitul de date (cum ar fi o matrice).

Comentarii (2)

O interfață este format din singleton variabile (public static final) și publică metode abstracte. În mod normal, vom prefera să utilizeze o interfață în timp real, atunci când știm ce să fac, dar nu't știu cum să fac.

Acest concept poate fi mai bine înțeleasă de exemplu:

Ia în considerare o Plată de clasă. Plata se poate face în mai multe moduri, cum ar fi PayPal, card de credit etc. Deci, în mod normal, vom lua Plata ca interfata noastra care conține un makePayment () metodă și de card de credit și PayPal sunt punerea în aplicare în două clase.

public interface Payment
{
    void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
    public void makePayment()
    {
        //some logic for PayPal payment
        //e.g. Paypal uses username and password for payment
    }
}
public class CreditCard implements Payment
{
    public void makePayment()
    {
        //some logic for CreditCard payment
        //e.g. CreditCard uses card number, date of expiry etc...
    }
}

În exemplul de mai sus card de credit și PayPal sunt două clasele de implementare /strategii. O Interfață de asemenea, ne permite conceptul de moștenire în Java care nu poate fi realizat de către o clasă abstractă.

Vom alege o clasă abstractă atunci când există unele caracteristici pentru care am știu ce să fac, și alte caracteristici pe care le știți cum să efectuați.

Luați în considerare următorul exemplu:

public abstract class Burger
{
    public void packing()
    {
        //some logic for packing a burger
    }
    public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
    public void price()
    {
        //set price for a veg burger.
    }
}
public class NonVegBerger extends Burger
{
    public void price()
    {
        //set price for a non-veg burger.
    }
}

Dacă adăugăm metode (concret/abstract), în viitor, la o anumită clasă abstractă, apoi punerea în aplicare clasă nu va avea nevoie de o schimbare de cod. Cu toate acestea, dacă adăugăm metode într-o interfață în viitor, trebuie să adăugați implementari pentru toate clasele care implementează interfața respectivă, în caz contrar compilare apar erori.

Există și alte diferențe, dar acestea sunt cele majore care ar fi putut fi ceea ce intervievatorul era de așteptat . Sperăm că acest lucru a fost de ajutor.

Comentarii (2)

Diferența dintre Abstact clasă și de interfață

  1. Clase abstracte față de interfețe în Java 8
  2. Diferență Conceptuală: Interfata Default Metode în Java 8

  3. Ce este Metoda Implicită?
  4. Metoda ForEach eroare de compilare rezolvate folosind Metoda Implicită
  5. Metoda implicită și Moștenirea Multiplă Ambiguitate Probleme
  6. Puncte importante despre java interface default metode: Java Interface Metodă Statică

  7. Java Interface Metodă Statică, cod de exemplu, metoda statică vs metoda implicită
  8. Puncte importante despre java interface metodă statică: Java Interfețe Funcționale



    Clase abstracte față de interfețe în Java 8

    Java 8 schimbări de interfață include metode statice și implicit metode în interfețe. Înainte de Java 8, am putea avea doar metoda declarații în interfețe. Dar din Java 8, putem avea default metode și metode statice în interfețe.

    După introducerea Metoda Implicită, se pare că interfețe și clase abstracte sunt aceleași. Cu toate acestea, ele sunt încă concept diferit în Java 8.

    clasă Abstractă poate defini constructor. Ele sunt mult mai structurate și poate fi un stat asociat cu ei. În timp ce în contrast, default metoda poate fi implementată numai în termeni de a invoca alte interfață metode, cu referire la o anumită implementare's de stat. Prin urmare, ambele folosesc pentru diferite scopuri și alegerea între două într-adevăr depinde de scenariu context. Diferență Conceptuală:

    Clasele abstracte sunt valabile pentru scheletice (de exemplu parțială) implementari de interfețe dar nu ar trebui să existe fără o interfață de potrivire. Deci, atunci când clase abstracte sunt reduse în mod eficient pentru a fi cu vizibilitate redusă, scheletice implementări de interfețe, poate default metode lua asta la fel de bine? Categoric: Nu! Implementarea de interfețe aproape întotdeauna necesită unele sau toate cele de clasă-clădire instrumente care implicit metodele lipsa. Și dacă unii interfață nu este în mod clar un caz special, care nu ar trebui să ducă în rătăcire. Interfata Default Metode în Java 8

    Java 8 introduce "Metoda Implicită" sau (Defender metode) caracteristică nouă, care permite dezvoltator pentru a adăuga noi metode pentru Interfețele fără a rupe existente punerea în aplicare a acestor Interfață. Acesta oferă flexibilitate pentru a permite o Interfață defini implementarea care va utiliza în mod implicit în situația în care un beton de Clasă nu reușește să asigure o punere în aplicare pentru această metodă. Să ia în considerare mic exemplu pentru a înțelege cum funcționează:

public interface OldInterface {
    public void existingMethod();
 
    default public void newDefaultMethod() {
        System.out.println("New default method"
               + " is added in interface");
    }
}

Următoarea Clasă va compila cu succes în Java JDK 8,

public class OldInterfaceImpl implements OldInterface {
    public void existingMethod() {
     // existing implementation is here…
    }
}

Dacă veți crea o instanță a OldInterfaceImpl:

OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod(); 

Metoda Implicită:

Implicit metode nu sunt finale, nu pot fi sincronizate și nu poate suprascrie Obiect metodele. Ele sunt întotdeauna publice, care grav limitează capacitatea de a scrie scurt și reutilizabile metode. Default metode pot fi furnizate la o Interfață, fără a afecta implementarea Clase ca acesta include o implementare. Dacă fiecare a adăugat metodă într-o Interfață definită cu implementarea apoi nr de punere în aplicare Clasă este afectat. O punere în aplicare Clasă poate trece peste implicit de implementare oferite de Interfata. Implicit metode permite pentru a adăuga noi funcționalități existente Interfețe fără a rupe în vârstă punerea în aplicare a acestor Interfețe. Când ne-am extinde o interfață care conține o metoda implicită, putem efectua următoarele,

  1. Nu suprascrie metoda implicită și va moșteni metoda implicită.
  2. Suprascrie metoda implicită similare la alte metode de suprascriere în subclasa.
  3. Redeclare default metodă abstractă, care forța subclasă a suprascrie.

    Metoda ForEach eroare de compilare rezolvate folosind Metoda Implicită

    Pentru Java 8, JDK colecții au fost extinse și forEach metodă se adaugă la întreaga colecție (care lucra în colaborare cu lambda). Cu mod convențional, codul arata ca mai jos,

public interface Iterable {
    public void forEach(Consumer<? super T> consumer);
}

Deoarece acest rezultat fiecare Clasa de punere în aplicare cu erori de compilare, prin urmare, o metoda implicită a adăugat cu o necesară punere în aplicare cu scopul existente punerea în aplicare nu ar trebui să fie schimbat. La Iterable Interfață cu metoda Implicită este de mai jos,

public interface Iterable {
    public default void forEach(Consumer
                   <? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}

Același mecanism a fost folosit pentru a adăuga Stream în JDK Interfață fără a rupe de punere în aplicare Clase.

Metoda implicită și Moștenirea Multiplă Ambiguitate Probleme

Deoarece java Clasa poate implementa mai multe Interfețe și fiecare Interfață poate defini metoda implicită cu aceeași metodă de semnătură, prin urmare, metode mostenite pot intra în conflict cu fiecare alte. Ia în considerare de mai jos de exemplu,

public interface InterfaceA {  
       default void defaultMethod(){  
           System.out.println("Interface A default method");  
    }  
}
 
public interface InterfaceB {
   default void defaultMethod(){
       System.out.println("Interface B default method");
   }
}
 
public class Impl implements InterfaceA, InterfaceB  {
}

Codul de mai sus va eșua pentru a compila cu următorul mesaj de eroare,

java: class Impl moștenește fără legătură implicite pentru defaultMethod() din tipuri InterfaceA și InterfaceB În scopul de a rezolva această clasă, trebuie să oferim default metoda de aplicare:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
    }
}

Mai mult, dacă vrem să invoce în aplicare implicit furnizat de către oricare dintre Interfata super, mai degrabă decât de punere în aplicare propriile noastre, putem face acest lucru, după cum urmează,

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
        // existing code here..
        InterfaceA.super.defaultMethod();
    }
}

Putem alege orice implementare implicită sau ambele, ca parte din noua noastră metodă. Puncte importante despre java interface default metode:

  1. Java interface default metode ne vor ajuta în extinderea interfețe fără a avea teama de rupere clasele de implementare.
  2. Java interface default metode are podul diferențele între interfețe și clase abstracte.
  3. Java 8 interfata default metode ne va ajuta în evitarea clase de utilitate, cum ar fi toate Colecțiile metodă de clasă pot fi furnizate în interfețele în sine.
  4. Java interface default metode ne va ajuta la eliminarea baza clasele de implementare, putem oferi default implementarea și punerea în aplicare clase pot alege care unul pentru a trece peste.
  5. Unul dintre principalele motive pentru introducerea default metodele din interfețele este de a spori Colecții de API în Java 8 pentru a sprijini lambda expresii.
  6. Dacă orice clasă în ierarhia are o metoda cu aceeasi semnatura, apoi default metode devin irelevante. O metoda implicită nu poate suprascrie o metodă de java.lang.Obiect. Raționamentul este foarte simplu, pentru că Obiectul este clasa de bază pentru toate clasele java. Deci, chiar dacă avem un Obiect din clasa metodelor definite ca implicit metodele din interfețele, acesta va fi inutil, deoarece clasa Object metoda va fi întotdeauna utilizate. De aceea, pentru a evita confuziile, nu putem avea default metode care sunt imperative Obiect metode de clasă.
  7. Java interface default metode sunt, de asemenea, menționată ca Apărător Metode sau Virtual metode de extensie. Resurse Link-Ul:

  8. https://stackoverflow.com/questions/19998454/interface-with-default-methods-vs-abstract-class-in-java-8
  9. Clasă abstractă versus interfață în JDK 8 era
  10. Interfață evoluția prin extensie virtuală metode

    Java Interface Metodă Statică

    Java Interface Metodă Statică, cod de exemplu, metoda statică vs metoda implicită Java interface static metodă este similară cu metoda implicită cu excepția faptului că nu putem trece peste ele în clasele de implementare. Această caracteristică ne ajută în a evita rezultate nedorite incase de punere în aplicare săraci în clasele de implementare. Să ne uităm la acest lucru cu un exemplu simplu.

public interface MyData {

    default void print(String str) {
        if (!isNull(str))
            System.out.println("MyData Print::" + str);
    }

    static boolean isNull(String str) {
        System.out.println("Interface Null Check");

        return str == null ? true : "".equals(str) ? true : false;
    }
}

Acum să vedem o implementare clasa care are isNull() metoda cu punerea în aplicare săraci.

public class MyDataImpl implements MyData {

    public boolean isNull(String str) {
        System.out.println("Impl Null Check");

        return str == null ? true : false;
    }

    public static void main(String args[]){
        MyDataImpl obj = new MyDataImpl();
        obj.print("");
        obj.isNull("abc");
    }
}

Rețineți că isNull(String str) este o simplă metodă de clasă, nu este imperativ interfața metodă. De exemplu, dacă vom adăuga @Override adnotare la isNull() metodă, se va duce în eroare de compilator. Acum, când vom rula aplicația, vom obține următorul rezultat.

Interfață Null Check

Impl Null Check Dacă am face interfața metoda de statică default, vom obține următorul rezultat. Impl Null Check

MyData Print::

Impl Null Check Java interface metodă statică este vizibil pentru interfață metode numai, dacă am elimina isNull() metoda de MyDataImpl clasa, nu vom fi capabili să-l folosească pentru MyDataImpl obiect. Cu toate acestea, ca și alte metode statice, putem folosi interfata metode statice folosind numele clasei. De exemplu, o declarație corectă va fi:

boolean result = MyData.isNull("abc");

Puncte importante despre java interface metodă statică:

  1. Java interface metodă statică este o parte de interfață, ne putem folosi de ea pentru punerea în aplicare clasa de obiecte.
  2. Java interface metodele statice sunt bune pentru furnizarea de utilități metode, de exemplu null verifica, de colectare, sortare etc.
  3. Java interface metodă statică ne ajută în furnizarea de securitate, pentru a nu permite punerea în aplicare clase de a trece peste ele.
  4. Nu putem defini interfața metodă statică pentru clasa Object metode, vom obține compiler eroare ca "Această metodă statică nu poate ascunde metodă de instanță de Obiect". Acest lucru este pentru că nu este permis în java, deoarece Obiectul este clasa de bază pentru toate clasele și nu putem avea un nivel de clasă metodă statică și un alt exemplu metoda cu aceeasi semnatura.
  5. Putem folosi java interface metode statice pentru a elimina clase de utilitate, cum ar fi Colecții și pentru a muta toate sunt metode statice pentru interfața corespunzătoare, care ar fi ușor de a găsi și de a folosi.

    Java Interfețe Funcționale

    Înainte de a încheia acest post, aș dori să ofere o scurtă introducere pentru interfețe Funcționale. O interfață cu exact o metodă abstractă este cunoscut sub numele de Interfață Funcțională. Un nou adnotare @FunctionalInterface a fost introdus pentru a marca o interfață Interfață Funcțională. @FunctionalInterface adnotare este o facilitate pentru a evita accidentale plus de metode abstracte în interfețe funcționale. E opțională, dar de bună practică de a utiliza. Funcționale interfețe sunt mult așteptatul și mult căutat caracteristică de Java 8, deoarece ne permite să folosim expresii lambda pentru a instantia ei. Un nou pachet java.util.funcția cu niște interfețe funcționale sunt adăugate pentru a oferi țintă tipuri de expresii lambda și metoda de referințe. Ne vom uita în interfețe funcționale și expresii lambda în posturi viitoare. Locul De Amplasare A Resurselor:

  6. Java 8 Schimbări de Interfață – metoda statica, metoda implicită
Comentarii (1)

Toate declarațiile sunt valabile, cu excepția prima declarație (după Java 8 release):

Metode de Java interface sunt implicit abstracte și nu pot avea implementari

Din documentația page:

O interfață este un tip de referință, similar cu o clasă, care poate să conțină numai constante, metoda de semnături, default metode, metode statice,și tipuri imbricate

Metoda organisme exista doar pentru default metode și metode statice.

Default metode:

O interfata poate avea default metode, dar sunt diferite de metode abstracte în clase abstracte.

Implicit metode permite să adăugați o nouă funcționalitate pentru interfețele de biblioteci și de a asigura binar compatibilitate cu codul scris pentru versiunile mai vechi ale acestor interfețe.

Atunci când vă extindeți o interfață care conține o metoda implicită, puteți face următoarele:

  1. Nu mai vorbim de metoda implicită la toate, care vă permite să interfata extinsa moșteni metoda implicită.
  2. Redeclare metoda implicită, ceea ce face "abstracte".
  3. Redefini metoda implicită, care suprascrie-l.

Metode Statice:

În plus față de implicit metode, puteți defini metode statice în interfețe. (O metodă statică este o metodă care este asociat cu clasa în care este definită, mai degrabă decât cu orice obiect. Fiecare instanță a clasei acțiunile sale metode statice.)

Acest lucru face mai ușor pentru tine de a organiza helper metode în biblioteci;

Exemplu de cod din pagina de documentare despre "interfață" a avea "statică" și "default" metode.

import java.time.*;

public interface TimeClient {
    void setTime(int hour, int minute, int second);
    void setDate(int day, int month, int year);
    void setDateAndTime(int day, int month, int year,
                               int hour, int minute, int second);
    LocalDateTime getLocalDateTime();

    static ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }
}

Utilizați liniile directoare de mai jos pentru a alege dacă doriți să utilizați o interfață sau clasă abstractă.

Interfață:

  1. Pentru a defini un contract ( de preferință apatrid - adică nu există variabile )
  2. La link-ul de legătură clase cu are o capacități.
  3. Să declare public variabile constante (imuabil de stat)

Clasă abstractă:

  1. Codul de strâns legate între mai multe clase. Acesta stabilește este o o legătură.

  2. Comun stat printre legate de clase ( stare poate fi modificat în clasele de beton)

Legate de posturi:

https://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo/33963650#33963650

https://stackoverflow.com/questions/10839131/implements-vs-extends-when-to-use-whats-the-difference/34977257#34977257

De a trece prin aceste exemple, puteți înțelege că

Fără legătură clase pot avea capacități prin interfață, dar legate de clase schimba comportamentul prin extensie de clase de bază.

Comentarii (5)

Explicația pare decent, dar poate fi privit ca ai citit-o tot de la un manual? :-/

Ceea ce am'm a mai deranjat despre este, cât de solidă a fost exemplul tau? Te-ai deranjat să includă aproape toate diferențele dintre abstracte și interfețe?

Personal, mi-ar sugera acest link: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE

pentru o listă exhaustivă de diferențe..

Sper că vă ajută pe dvs. și pe toți ceilalți cititori în viitor interviuri

Comentarii (2)

Multe junior dezvoltatorii de a face greseala de a gândi de interfețe, abstracte și concrete clase ca mici variații de același lucru, și alege una dintre ele pur și simplu pe motive tehnice: Nu am nevoie de mai multe moștenire? Am nevoie de un loc pentru a pune frecvente metode? Am nevoie să deranjez cu ceva, altele decât doar un beton de clasă? Acest lucru este greșit, și-a ascuns in aceste întrebări este principala problemă: "I". Atunci când scrie cod pentru tine, de unul singur, rareori se gândească la alte prezente sau viitoare dezvoltatorii lucrează la sau cu cod. Interfețe și clase abstracte, deși aparent similare din punct de vedere tehnic, au sensuri complet diferite și scopuri.

Rezumat

  1. O interfață definește un contract că unele implementare va îndeplini pentru tine.
  2. O clasă abstractă oferă un comportament implicit care implementarea pot reutiliza. Aceste două puncte de mai sus este ceea ce am'm în căutarea pentru atunci când intervievarea, și este un compact destul de sumar. Citiți mai departe pentru mai multe detalii.

    Alternative rezumat

  3. O interfață este pentru definirea Api-uri publice
  4. O clasă abstractă este pentru uz intern, și pentru definirea SPIs

    De exemplu ###

    Pentru a pune altfel: Un beton de clasa lucrează, într-un mod foarte specific. De exemplu, un ArrayListfoloseste-o zonă contiguă de memorie pentru a stoca o listă de obiecte într-un mod compact, care oferă rapid de acces aleatoriu, repetare, și în loc schimbări, dar este groaznic la inserții, deleții, și, ocazional, chiar și completări; între timp, oLinkedListfoloseste dublu-noduri legate pentru a stoca o listă de obiecte, care în schimb oferă rapid iterație, în loc schimbări, și de inserție/deleție/plus, dar este groaznic la acces aleator. Aceste două tipuri de liste sunt optimizate pentru diferite cazuri de utilizare, și contează foarte mult cum te-ai&#39;re de gând să le folosească. Când te&#39;re încercarea de a stoarce de performanță dintr-o listă pe care o&#39;re puternic interacționează cu, și atunci când alege tipul de listă este de până la tine, ar trebui să alegeți cu grijă care o&#39;re instantierea. Pe de altă parte, nivelul ridicat de utilizatori de o listă don&#39;t într-adevăr grijă cum este, de fapt puse în aplicare, și acestea ar trebui să fie izolate de la aceste detalii. Las&#39;s imaginați-vă că Java n&#39;t expune "Lista" de interfață, dar a avut doar un beton "Listă" de clasa care&#39;s, de fapt, ce LinkedList este acum. Toate dezvoltatorii Java ar trebui adaptate codul lor pentru a se potrivi detaliile de implementare: evita cu acces aleator, se adaugă un cache pentru a accelera accesul, sau doar reimplementezeArrayList pe cont propriu, deși ar fi incompatibilă cu toate celelalte coduri care funcționează de fapt cu "Lista" numai. Asta ar fi groaznic... Dar acum imaginați-vă că Java masterat dai seama de fapt ca o lista inlantuita este teribil pentru cele mai actuale cazuri de utilizare, și a decis să treacă la o listă matrice pentru singura lor "Lista" de clasă disponibile. Acest lucru ar afecta performanța de fiecare program Java în lume, și oamenii nu't fi fericit despre asta. Și vinovatul principal este că detaliile de implementare au fost disponibile, și dezvoltatorii presupune că aceste detalii sunt de un contract permanent care se pot baza. Acesta este motivul pentru's important pentru a ascunde detaliile de implementare, și de a defini doar un rezumat contract. Acesta este scopul de o interfață: defini ce fel de intrare o metodă acceptă, și ce fel de ieșire este de așteptat, fără a expune tot curajul care m-ar tenta programatori pentru a optimiza codul lor pentru a se potrivi detalii interne care s-ar putea schimba cu orice viitor update. O clasă abstractă este la mijloc între interfețe și clase de beton. Acesta ar trebui să ajute implementări în comun sau plictisitor cod. De exemplu, AbstractCollection oferă implementări de bază pentru isEmptybazează pe dimensiunea este de 0, "conține" ca repeta și compara,addAll` ca a repetat "add", și așa mai departe. Acest lucru vă permite implementări accent pe componentele esențiale care diferențiază între ele: modul de a stoca și de a prelua datele.

    Un alt punct de vedere: APIs versus SPIs

    Interfețele sunt scăzut de coeziune gateway între diferite părți ale codului. Se permite bibliotecilor să existe și să evolueze fără a rupe fiecare bibliotecă utilizator, atunci când ceva se schimbă pe plan intern. L's a numit Programare a aplicațiilor Interfata, nu de Programare a aplicațiilor Clase. Pe o scară mai mică, au, de asemenea, permite mai multor dezvoltatori pentru a colabora cu succes pe proiecte de mare amploare, prin separarea diferite module prin bine documentate interfețe. Clasele abstracte sunt de înaltă coeziune ajutoare pentru a fi utilizate atunci când se implementează o interfață, presupunând un anumit nivel de detalii de implementare. Alternativ, clase abstracte sunt folosite pentru definirea SPIs, Furnizor de Servicii de Interfețe. Diferența între un API și un SPI este subtil, dar important: pentru un API, accentul este pus pe cine utilizează, iar pentru un SPI accentul este pus pe cine implementează a. Adăugarea de metode de la un API este ușor, toți utilizatorii existenți de API-ul încă va compila. Adăugarea de metode pentru a o SPI este greu, deoarece fiecare furnizor de servicii (concrete de punere în aplicare), va trebui să pună în aplicare noi metode. Dacă interfețele sunt folosite pentru a defini un SPI, un furnizor va trebui să-i elibereze o nouă versiune, ori de câte ori SPI modificările de contract. Daca clase abstracte sunt folosite în loc de asta, noi metode ar putea să fie definită în termeni de existent metode abstracte, sau la fel de gol arunca nu a implementat excepție stubs, care va permite cel puțin o versiune mai veche de un serviciu de implementarea a încă compila și rula.

    O notă pe Java 8 și implicit metodele

    Deși Java 8 introdus default metode pentru interfețe, ceea ce face linia dintre interfețe și clase abstracte chiar mai cețos, asta era't, astfel încât implementari pot reutiliza codul, dar pentru a face mai ușor de a schimba interfețe care servesc atât ca un API și ca un SPI (sau sunt greșit utilizate pentru definirea SPIs în loc de clase abstracte).

    "cunoștințe Carte"

    Detalii tehnice prevăzute în OP's de răspuns sunt considerate "cunoștințe carte" pentru că aceasta este, de obicei, abordarea utilizată în școală și în cele mai multe tehnologii de cărți despre un limbaj: * ce un lucru este, nu cum** să-l folosească în practică, mai ales în scară largă de aplicații. Aici's o analogie: ar trebui întrebarea a fost:

    Ce este mai bine să închirieze pentru noaptea balului, o mașină sau o cameră de hotel? Tehnice răspunsul pare a fi: ei Bine, într-o mașină, poți să o faci mai devreme, dar într-o cameră de hotel, puteți face mai confortabil. Pe de altă parte, camera de hotel este într-un singur loc, în timp ce în mașină, puteți face în mai multe locuri, cum ar fi, să's spun poti sa te duci la vista point pentru o vedere frumoasă, sau într-un cinematograf în aer, sau în multe alte locuri, sau chiar în mai mult de un singur loc. De asemenea, hotelul cameră are un duș. Că este adevărat, dar ratează complet punctele care acestea sunt două lucruri complet diferite, și ambele pot fi folosite în același timp pentru diferite scopuri, și "face" aspect nu este cel mai important lucru despre oricare dintre cele două opțiuni. Răspunsul lipsit de perspectivă, se arată un mod imatur de gândire, în timp ce în mod corect prezentarea adevărat "fapte".

Comentarii (2)

O interfață este o "contract" în cazul în care clasa care implementează contractul promite să pună în aplicare metode. Un exemplu în care am avut de a scrie o interfață în loc de o clasă a fost atunci când am fost a face upgrade un joc de la 2D la 3D. Am avut de a crea o interfață pentru clasele de acțiuni între 2D și 3D versiune a jocului.

package adventure;
import java.awt.*;
public interface Playable {
    public void playSound(String s);
    public Image loadPicture(String s);    
}

Atunci pot să pună în aplicare metode bazate pe mediu, în timp ce încă posibilitatea de a apela aceste metode la un obiect care nu't știu ce versiune a jocului, care este de încărcare.

public class Aventura se extinde JFrame implements Redate

public class Dungeon3D se extinde SimpleApplication implementează Redate

public class Principal se extinde SimpleApplication implementează AnimEventListener, ActionListener, Redate

De obicei, în gameworld, lumea poate fi o clasă abstractă care efectuează metode pe joc:

public abstract class World...

    public Playable owner;

    public Playable getOwner() {
        return owner;
    }

    public void setOwner(Playable owner) {
        this.owner = owner;
    }
Comentarii (0)

Ce să gândesc în felul următor:

  • O relație între o clasă și o clasă abstractă este de tip "este un"
  • O relație între o clasă și o interfață este de tip "a-un"

Deci, atunci când aveți o clasă abstractă Mamifere, o subclasă Umane, și o interfață de Conducere, atunci se poate spune

  • fiecare Om este un Mamifer
  • fiecare Om are-o Conducere (comportament)

Sugestia mea este că această carte cunoștințe expresie indică faptul că el a vrut să audă diferență semantică între cele două (ca și alții de aici sugerat deja).

Comentarii (0)

Clase abstracte nu sunt pură abstracție bcz sa colecție de beton(implementat metode) precum și metode neimplementate. Dar Interfețele sunt pură abstracție bcz există doar metode neimplementate nu metode concrete.

Ce clase Abstracte?

  1. Dacă utilizatorul vrea să scrie funcționalități comune pentru toate obiectele.
  2. Clasele abstracte sunt cea mai bună alegere pentru reimplementare în viitor, pentru a adăuga mai multă funcționalitate, fără a afecta de utilizator final.

Interfețe De Ce?

  1. Dacă utilizatorul vrea să scrie diferite funcționalități care ar fi diferite funcționalități pe obiecte.
  2. Interfețele sunt cea mai bună alegere pe care dacă nu este nevoie de a modifica cerințele odată interfața a fost publicat.
Comentarii (0)

O interfata este ca un set de gene care sunt documentate public de a avea un fel de efect: UN test ADN va spune-mi dacă am'am - și dacă o fac, nu pot face public este cunoscut faptul că m-am'm a "transport" și o parte din comportamentul meu sau de stat va fi conformă cu ele. (Dar, desigur, am putea avea multe alte gene care oferă trăsături în afara acestui domeniu.)

O abstract class este ca strămoș mort de un singur-sex specii(): Ea poate't fi adus la viață, dar o viață (de exemplu, non-abstract*) descendentul moștenește toate genele ei.

(*) Pentru a întinde această metaforă, să's spun tuturor membrilor specii trăiesc la aceeași vârstă. Acest lucru înseamnă că toate strămoșii un strămoș mort trebuie să fie, de asemenea, mort - și, de asemenea, toți descendenții de viață strămoș trebuie să fie în viață.

Comentarii (0)

Alegeți Interfața în Java pentru a evita Diamond Problemă în moștenirea multiplă.

Dacă doriți ca toate metodele tale să fie puse în aplicare de către clientul tău ați merge pentru interfață. Aceasta înseamnă că design întreaga aplicație la abstract.

Alegeți clasă abstractă dacă știți deja ce este în comun. De exemplu, să Ia o clasă abstractă "Auto". La nivel mai mare pună în aplicare în comun de mașini metode, cum ar fi calculateRPM(). Este o metodă comună și te lași clientul să pună în aplicare propriul său comportament ca calculateMaxSpeed() etc. Probabil că te-aș fi explicat prin acordarea câteva timp real exemple care ați întâlnit în viața de zi cu zi de locuri de muncă.

Comentarii (0)

Fac interviuri pentru muncă și m-aș uita în sens defavorabil pe răspunsul tău la fel de bine (scuze dar sunt foarte sincer). Nu suna ca tine'am citit despre diferența și revizuit un răspuns, dar poate că nu au folosit-o în practică.

O explicație cu privire la ce ar folosi fiecare poate fi mult mai bine decât a avea o explicație exactă a diferenței. Angajatori ultimatley vreau comparing să facă lucruri pe care nu le cunosc, care poate fi greu pentru a demonstra într-un interviu. Răspunsul dat ar fi bine dacă aplică o tehnică sau o documentație pe bază de muncă, dar nu o dezvoltatorii de rol.

Cel mai bun de noroc cu interviuri în viitor.

De asemenea, răspunsul meu la această întrebare este mai mult despre tehnica interviului, mai degrabă decât materialul tehnic le-ați furnizat. Probabil, ia în considerare citind despre el. https://workplace.stackexchange.com/ poate fi un loc excelent pentru acest tip de lucru.

Comentarii (2)

O interfață este pur abstractă. nu avem niciun cod de punere în aplicare în interfață.

Clasă abstractă conține ambele metode și punerea sa în aplicare.

[click aici pentru a viziona tutorial pe interfețe și clase abstracte][1]

Comentarii (0)

Principala diferență ce am observat a fost ca clasă abstractă ne oferă unele comune de comportament implementat deja și subclase are nevoie doar de a pune în aplicare funcționalitate specifică corespunzătoare a acestora. în cazul în care pentru o interfață va specifica doar ce sarcini trebuie să fie făcut și nu implementări va fi dat de interfață. Pot spune ca este specifică contractului între sine și implementat clase.

Comentarii (0)

Chiar m-am confruntat cu aceeași întrebare în mai multe interviuri și crede-mă că timpul tău mizerabil de a convinge intervievatorul. Dacă am inerente toate răspunsurile de mai sus, atunci trebuie să mai adaug un punct-cheie pentru a face mai convingătoare și utilizarea OO la cele mai bune

În cazul în care nu planificare orice modificare în normele , pentru subclasa să fie urmat, pentru o lungă perioadă de viitor, du-te pentru interfață, ca tu wont a fi capabil de a modifica în ea și dacă face acest lucru, aveți nevoie pentru a merge pentru schimbări în toate celelalte sub-clase, întrucât, dacă credeți că, doriți să reutilizați funcționalitatea, stabilim niște reguli și, de asemenea, să-l deschidă pentru modificarea, du-te pentru o clasă Abstractă.

Cred că în acest fel, ar fi folosit un consumabil serviciu sau a furnizat un cod de lume și Aveți o șansă de a modifica ceva, să presupunem că un control de securitate Și Dacă eu sunt un consumator de cod și într-O dimineață, după o actualizare , am găsi tot citit marchează în Eclipse, întreaga aplicație este în jos. Deci, pentru a preveni astfel de coșmaruri, utilizarea Abstract peste Interfețe

Cred că acest lucru ar putea convinge Intervievatorul pentru a o măsura...Fericit Interviuri Înainte.

Comentarii (0)

Când am încercat să împărtășiți comportament între 2 strâns legate de cursuri, am crea o clasă abstractă care deține comportament comun și servește ca un părinte pentru ambele clase.

Atunci când sunt încercarea de a defini un Tip, o listă de metode care un utilizator de obiect poate fiabil chema, apoi am crea o interfață.

De exemplu, niciodată nu m-aș crea o clasă abstractă cu 1 beton subclasă pentru clasele abstracte sunt despre schimbul de comportament. Dar s-ar putea foarte bine să creați o interfață cu o singura aplicare. Utilizatorul de codul meu a câștigat't știu că există doar o singură aplicare. Într-adevăr, într-o versiune viitoare pot exista mai multe implementari, toate din care sunt subclase ale unor noua clasă abstractă care nu't chiar exista atunci când am creat interfață.

Care ar fi putut părea un pic prea livresc, prea (deși am mai vazut asta pana acum oriunde-mi amintesc). Dacă intervievatorul (sau OP) într-adevăr a vrut mai mult de la experiența mea personală, pe care, mi-ar fi fost gata cu anecdote de o interfață a evoluat din necesitatea și invers.

Un lucru mai mult. Java 8 acum, vă permite de a pune codul implicit într-o interfață, mai estompează linia dintre interfețe și clase abstracte. Dar din ceea ce am văzut, această caracteristică este prea des folosit chiar și de către factorii de decizie din Java, bibliotecile de bază. Această caracteristică a fost adăugat, și pe bună dreptate, să facă posibilă pentru a extinde o interfață fără a crea binar de incompatibilitate. Dar dacă faci un brand nou Tip de definirea unei interfețe, atunci interfața ar trebui să fie DOAR o interfață. Dacă vrei să oferi, de asemenea, cod comun, apoi prin toate mijloacele a face un helper class (abstracte sau concrete). Don't fi aglomera interfata de la început cu funcționalitate care poate doriți să se schimbe.

Comentarii (0)

Diferența de bază între interfață și clasă abstractă este, interfață acceptă moștenirea multiplă, dar abstract class.

În clasă abstractă, de asemenea, vă poate oferi toate metode abstracte ca interfață.

de ce o clasă abstractă este necesar?

În unele scenarii, în timp ce prelucrarea cererea utilizatorului, în clasă abstractă nu't știu ce utilizatorul de intenție. În acest scenariu, vom defini o metodă abstractă în clasă și cere utilizatorului care a extinde acest curs, vă rugăm să transmiteți intenția dumneavoastră în metodă abstractă. În acest caz, clase abstracte sunt foarte utile

De ce interfața este necesar?

Las's spun, am un lucru pe care nu-l't au experiență în acest domeniu. De exemplu, dacă doriți pentru a construi o clădire sau baraj, atunci ce vei face în acest scenariu?

  1. vei identifica care sunt cerințele dumneavoastră și de a face un contract cu cerințele.
  2. Apoi suna la Licitații pentru a construi dvs. de proiect
  3. Cine a mai construi proiectul, care ar trebui să satisfacă cerințele dumneavoastră. Dar construcția logică este diferită de la un furnizor la un alt furnizor.

Aici am don't deranjat despre logica cum au construit-o. Obiectul final îndeplinite cerințele mele sau nu, că singurul meu punct cheie.

Aici cerințele dumneavoastră numit interfață și constructori sunt numite implementeaza.

Comentarii (0)

În clasă abstractă, puteți scrie default implementarea de metode! Dar în Interfață nu se poate. Practic, În interfața există funcții virtuale pure, care trebuie să fie puse în aplicare de către clasa care implementeaza interfata.

Comentarii (0)