2011-12-07 14 views
12

se lanciamo un oggetto su un'interfaccia, questo oggetto non sarà in grado di chiamare i propri metodi? nel seguente esempio, myObj sarà in grado di chiamare i metodi MyInterface?esegue il cast di un oggetto su un'interfaccia in java?

MyInterface myObj = new Obj(); 

Se questo è corretto, qual è la differenza tra questi 2 oggetti:

MyInterface myObj = new Obj(); 

MyInterface mySec = new Sec(); 

Grazie per il vostro aiuto

+0

[questo] (http://docs.oracle.com/javase/tutorial/java/concepts/interface.html) potrebbe essere di aiuto. – Nerdtron

risposta

16
MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

Perché ciò sia legale, sia Obj e Sec sarà devono essere implementatori di MyInterface. La differenza tra questi due oggetti sarebbe in cui forniscono tale implementazione. Obj e Sec potrebbero fare due cose molto diverse o molto simili, ma la loro comunanza è che aderirebbe ad un contratto su cui si poteva fare affidamento. Si consideri di avere un metodo

public void doSomethingWith(MyInterface thing) { 
    thing.frob(); 
} 

Ogni oggetto, myObj e mySec, potrebbe essere passato in questo metodo, e questo metodo potrebbe quindi utilizzare frob metodo dell'oggetto (frob supponendo che fa parte della dichiarazione di interfaccia). Questo è liberando. Questo ti permette di fare cose molto potenti, programmando interfacce e non implementazioni. Ad esempio, è possibile estendere la funzionalità delle classi e non modificare una riga di codice in tali classi, è sufficiente passare una diversa implementazione di una dipendenza. Non sei legato a, o accoppiato con, un qualsiasi impianto all'interno del metodo doSomethingWith.

ma ho anche letto che se noi dichiariamo le myObj oggetto come MyInterface, myObj non sarà in grado di utilizzare i propri metodi (dalla classe Obj), è che correggere

Internamente , le istanze di Obj continueranno ad avere pieno accesso all'API Obj. myObj è ancora un Obj, sarà sempre in grado di utilizzare i propri dettagli di implementazione.

public interface MyInterface { 
    void frob(); 
} 

public class Obj implements MyInterface { 

    public void frob() { 
     doFrobbing(); 
    } 

    private void doFrobbing() { 
     System.out.println("frobbing"); 
    } 

    public static void main(String[] args) { 
     MyInterface myObj = new Obj(); 
     myObj.frob(); // still internally calls doFrobbing() 
     ((Obj)myObj).doFrobbing(); // visible only via class reference 
    } 
} 

istanze di Obj saranno ancora le istanze di Obj, e quei casi saranno ancora in grado di utilizzare doFrobbing. Esternamente, le persone utilizzando quelle istanze tramite il riferimento all'interfaccia saranno solo in grado di accedere ai metodi di interfaccia.

+0

grazie anthony per questa grande spiegazione, lo capisco, e ancora di più ora grazie, ma leggo anche che se dichiariamo l'oggetto 'myObj' come MyInterface,' myObj' non sarà in grado di usare i propri metodi (dal classe 'Obj'), è corretto? – Paul

+0

@Paul, buona domanda, risposta aggiornata. –

+0

grazie per l'aggiornamento, quindi qual è il punto per fare questo? (nascondendo i metodi di 'Obj' quando' MyInterface' è il tipo) Un'interfaccia "esiste" per "aggiungere" alcuni metodi a un oggetto, giusto ?, quindi perché nasconde gli altri metodi? (o forse non ci sono ragioni per farlo, funziona perché, come regola generale in ogni linguaggio di programmazione, un "tipo" funziona così?) – Paul

1

Solo i metodi nell'interfaccia sono visibile, ma tutti i metodi nell'oggetto possono ancora essere richiamati, a condizione che siano resi accessibili altrimenti. Per esempio:

public interface MyInterface { 
    String getName(); 
} 

public class Obj implements MyInterface { 
    private String getFirstName() { 
     return "John"; 
    } 

    private String getLastName() { 
     return "Doe"; 
    } 

    @Override 
    public String getName() { 
     return getFirstName() + " " + getLastName(); 
    } 
} 

public class Sec implements MyInterface { 
    private String getDate() { 
     return new Date().toString(); 
    } 

    @Override 
    public String getName() { 
     return getDate(); 
    } 
} 

Nei casi di cui sopra, sia Obj e Sec può chiamare i loro membri privati, anche se non saranno visibili in altre classi. Quindi quando dici ...

MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

...come è stato chiesto nella domanda, mentre è vero che in myObj e mySec l'unico metodo visibile è getName(), l'implementazione sottostante può essere diversa.

+0

grazie jonathan per questa grande spiegazione, mmh, ok lo capisco un po 'di più, quindi se i metodi di 'Obj' non sono visibili da altre classi, nel qual caso importa? (hai un semplice esempio?) – Paul

+0

Scusa, non sono sicuro di aver capito la tua domanda. –

1

Non c'è differenza. Sarai in grado di invocare i metodi di interfaccia MyInterface su myObj e mySec. Ovviamente il tuo codice verrà compilato solo se sia Obj sia implementano l'interfaccia Myinterface.

+0

grazie per la tua risposta rapida, ecco la cosa: cosa succede se abbiamo avviato il progetto senza interfacce, e quindi vogliamo implementare un'interfaccia perché abbiamo bisogno di più metodi da aggiungere sulle classi 'A' e' B': perderemo i metodi precedenti da 'A' e' B' perché dichiareremo 'a' e' b' come oggetti di I ... – Paul

+0

@Paul Le interfacce esistono allo scopo di aggiungere qualche * interfaccia * comune (o in altre parole un contratto) a classi diverse e lasciando che quelle classi implementino effettivamente la * funzionalità * in base al contratto. In realtà non è necessario utilizzare le interfacce se si desidera aggiungere nuovi metodi a una classe. Ecco una semplice definizione di cosa sia un'interfaccia: http://docs.oracle.com/javase/tutorial/java/concepts/interface.html – Strelok

+0

grazie a Strelok, il mio equivoco riguarda la modifica del "Tipo" di un oggetto, e metti l'interfaccia come "Tipo", questo significherebbe che i metodi dell'obj non sono più "visibili" ... il che mi confonde un po '. Ho il principio delle interfacce però, capisco che le interfacce sono alcuni metodi che condividono 2 classi, ma quello che non sono sicuro di capire è: se "Interface" è il tipo, gli altri metodi della classe myObj hanno vinto essere più visibili – Paul

0

Nel codice che hai mostrato di non eseguire mai lanci.

Un uso tipico di un'interfaccia è definire alcuni metodi che saranno disponibili, senza preoccuparsi dell'implementazione concreta.

Un bell'esempio di questo sono gli ascoltatori nello standard JDK. Ad esempio lo PropertyChangeListener. Questa è un'interfaccia che definisce un metodo che può essere chiamato quando 'una proprietà viene cambiata'. Un tipico uso di questa interfaccia è quello di collegarlo ad una classe che ha proprietà, e questa classe avviserà quegli ascoltatori quando una delle sue proprietà è cambiata.

Alla classe non importa cosa faranno quegli ascoltatori. Si basa solo sul fatto che questo metodo propertyChange sarà presente e chiama tale metodo.

La classe può chiamare questo metodo solo sul listener, poiché conosce solo il metodo definito nell'interfaccia. Se quegli ascoltatori hanno altri metodi, possono chiamarli da soli, ma solo perché sanno che sono più dell'interfaccia.

0
MyInterface mi = new Obj(); 
mi.getInterfaceMethods(); (methods in the MyInterface) 

if(mi instanceof Obj) { 
    mi.getObjMethods(); (methods in the Obj) 
} 
0

La modifica del tipo di una variabile (ad esempio un riferimento) non modifica l'oggetto stesso. Un oggetto può sempre chiamare i propri metodi, indipendentemente dal tipo di variabili dichiarate che fanno riferimento ad esso.

1
MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

si dichiara un'istanza di un MyInterface nome myObj. Inizializza con il nuovo Obj(); che è autorizzato dal compilatore se Obj implementa MyInterface. myObj può chiamare solo i metodi MyInterface, ovviamente. Lo stesso per la seconda riga.

Ecco un codice di esempio per provare:

public class Test { 

    public static void main(String args[]){ 
      A a = new A(); 
      a.say(); 
      a.a(); 

      B b = new B(); 
      b.say(); 
      b.b(); 

      I ia = new A(); 
      ia.say(); 
      ia.a(); // fail 
    } 

} 

interface i { 
    public void say(); 
} 

class A implements i { 
    public void say(){ 
     System.out.println("class A"); 
    } 
    public void a(){ 
     System.out.println("method a"); 
    } 
} 

class B implements i { 
    public void say(){ 
     System.out.println("class B"); 
    } 
    public void b(){ 
     System.out.println("method b"); 
    } 
} 
+0

grazie a kbdjockey per la tua risposta: ok, ma se avessimo iniziato il progetto senza interfacce, e poi avremmo implementato un'interfaccia perché abbiamo bisogno di più metodi da aggiungere sulle classi 'A' e' B': perderemo i metodi precedenti da 'A' e' B' perché dichiareremo 'a' e' b' come oggetti di I ... – Paul

+0

Solo perché 'A' e' B' implementano 'I' non significa che tu devono istanziarli come tali. Puoi ancora dire 'A myObj = new A()', e accedere a tutti i metodi di 'A' (compresi quelli sovrascritti da' I'). –

0

Una semplice analogia:

consideri uno Chef (Interface). E ci sono chef cinesi (classi) e chef americano (classi). Ora, c'è un hotel che guarda di reclutare uno chef sulla base di alcuni criteri di ammissibilità come

  • può cucinare non-vegetariano
  • possono cucinare vegetariano
  • hanno esperienza di 5 anni

Qui, l'ammissibilità è il contesto in cui viene valutata la persona del tipo Chef (funzionalità Tipi). Ora, ci possono essere casi in cui lo chef cinese può anche cucinare frutti di mare, piatti italiani ecc. Così potrebbe essere il caso con la controparte americana. Tutto ciò può sembrare irrilevante per il direttore dell'hotel, poiché si preoccupa solo dei criteri richiesti.

I cuochi che lavorano in un hotel sono analoghi all'oggetto tipo Chef utilizzato nel codice. Il lavoro ovvio sarebbe quello di cucinare cibi vegetariani e non vegeteriani (criteri o metodi di interfaccia). Ciò non significa che l'Hotel non possa utilizzare le abilità di produzione di frutti di mare dello chef cinese.

È solo una questione di specificare quali competenze (funzionalità) l'Hotel sta cercando.

Spero che tu abbia l'idea.

Problemi correlati