2015-06-09 9 views
6

Linguaggi di programmazione orientati agli oggetti, ad es. java, C#, ... supporto per l'oggetto typecasting. Per esempio, questo è perfettamente valido in Java:Il casting di oggetti è una buona pratica?

URL url = new URL("url");  
URLConnection conn = url.openConnection(); 

if(!conn instanceof HttpURLConnection) 
    throw new Exception("not http request"); 

HttpURLConnection con = (HttpURLConnection) conn; 

Oppure un altro esempio di base che ho provato:

public class Base 
{ 
    public void base(){} 
} 

public class Derived extends Base 
{ 
    public void derived(){} 
} 

Base b = new Derived(); 
b.base(); 

classe derivata ha tutta la classe metodi di base ha, più più. Non c'è motivo per cui non sia possibile creare una classe base chiamando il costruttore della classe derivata.

Mi sono anche imbattuto in questo link http://www.volantec.biz/castingObjects.htm che spiega come funziona il typecasting degli oggetti internamente. Fin qui, ok.

Ma perché il primo esempio non utilizza HttpURLConnection con = new HttpURLConnection("url address") (so che HttpURLConnection è una classe astratta). Sembra solo più chiaro, più semplice. D'altra parte quando hai a che fare con interfaces, object typecasting comes in handy. Un altro esempio è la lista List<Object>, che a volte vedo in alcune classi. Significa che puoi salvare ogni classe possibile in questa lista. In seguito puoi lanciarlo sul suo originale, se sai di che tipo si tratta. Non sarebbe più semplice salvare solo classi specifiche da elencare, ad esempio List<String>, List<MyClass>. Sta usando le buone pratiche di progettazione List<Object>?

+2

Il casting obbligatorio su 'HttpURLConnection' è un esempio perfetto di OOD errato. Per quanto riguarda gli elenchi generici: dipende, ma preferirei elenchi parametrizzati quanto più possibili, così potrei catturare molte eccezioni del cast di tipo runtime al momento della compilazione. –

+3

Bene, la risposta è nella domanda: HttpUrlConnection è una classe astratta, quindi non è possibile creare un'istanza di HttpUrlConnection. Solo di una sottoclasse. E questo è ciò che url.openConnection() fa. –

+0

@ JBNizet L'ho menzionato tra parentesi. Sono consapevole che HttpURLConnection è una classe astratta, quindi non puoi creare un'istanza come hai menzionato. Hai ragione, volevo solo dimostrarlo, forse qualche altro esempio è più appropriato. – broadband

risposta

7

Durante la progettazione di una gerarchia di classi, bisogna sempre mantenere la Liskov's Substitution Principle (aka, LSP) a mente:

tipi derivati ​​devono essere completamente sostituibili per i loro tipi di base.

In altre parole, per decidere se è necessario estendere una classe, è necessario chiedersi se i componenti che dipendono dalla nuova classe sarebbero ben serviti se si modifica la sua classe base.

Il problema con il casting è che se è necessario convertirlo in una classe derivata, significa che si sta violando l'LSP.

Se è necessario assicurarsi che un oggetto provenga da un'implementazione specifica quando ci si aspetta un'interfaccia, allora c'è sicuramente qualcosa di sbagliato nel progetto.

Le interfacce sono come i contratti. Se stai utilizzando un metodo dell'implementazione che non è nell'interfaccia, significa che stai violando quel contratto, creando un accoppiamento tra il tuo codice e un'implementazione.

Ricordare che il codice deve sempre rely on abstractions rather than concretions.

0

eseguendo il casting con la classe Object e fondamentalmente dando ogni autorizzazione disponibile alle classi derivate, cioè una funzione non rifiuterà mai i parametri imminenti, dal momento che si è previsto che l'Oggetto sia accessibile in modo pericoloso, e come da @Henrique sta dicendo che è giusto che se hai bisogno di assicurarti che un oggetto sia un'implementazione specifica quando aspetti un'interfaccia, allora c'è sicuramente qualcosa di sbagliato nel tuo progetto.

+1

si prega di evitare la forma abbreviata di inglese – lalithkumar

+0

Api è stato progettato da Java - https://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html. – broadband

+0

si prega di citare il riferimento completo come cosa intendete per 'API è stato progettato da JAVA' –