Perché i membri statici non possono essere astratti e non implementano il polimorfismo? [duplicare]

1

Sono uno sviluppatore Java / C # / PHP, attraverso la mia esperienza di programmazione OOP mi trovo a fare la stessa domanda: Perché i membri statici non possono essere astratti e non implementano il polimorfismo specialmente in situazioni che coinvolgono metodi di fabbrica, ad esempio:

abstract class Resource {
    public void doSomething();
}

abstract class User<resource extends Resource> {

    //if i want to instantiate resource, 
    //my only option here is to create an abstract factory in user class
    protected abstract resource create();

    public void use(){
        create().doSomething();
    }

}

class FileUser extends User<File> {

    //It's a bit clumsy, isn't it?
    @Override
    protected Internet create() {
        return new File();
    }

}

quando i metodi statici astratti mi libererebbero da queste fabbriche astratte: (Sotto non è un codice valido)

abstract class Resource {
    public void doSomething();
    //Im not sure how the child class would get passed though
    static abstract Resource create();
}

abstract class User<resource extends Resource> {

    public void use(){
        resource.create().doSomething();
    }

}

Quindi qualcuno sa perché questo tipo di comportamento non sarebbe approvato in OOP? Scusa se sembra una domanda stupida.

    
posta Ben 26.10.2014 - 13:44
fonte

3 risposte

3

I metodi statici sono non fanno parte della programmazione orientata agli oggetti , sono praticamente funzioni con nomi diversi . Pensaci in questo modo, cosa significa avere un metodo abstract o avere un comportamento polimorfico ?

Significa che puoi fare questo:

function connectToDB(/*string */ $dsn, /* string */ $user, /*string*/ $password, /*Logger*/ $logger) {
    $pdo = new PDO($dsn, $user, $password);
    //This is polymorphic, you can pass any object that implements the Logger
    //interface, without exposing to this function what logging mechanism is used.
    $logger->log('Connected to database!'); 
}

Come faresti con metodi statici? I metodi statici includono il nome della classe nella chiamata, non è possibile (ragionevolmente) passare qualsiasi logger desiderato e utilizzare il metodo statico log su di esso.

Lo stesso vale per l'astratto. Non ha proprio senso un metodo statico astratto.

    
risposta data 26.10.2014 - 15:06
fonte
2

Non sono esperto in nessuna delle lingue sopra menzionate, ma una breve lettura dei documenti Java e l'affermazione implicita da parte tua che tutti agiscono allo stesso modo mi portano alla comprensione che tutti usano la staticità nello stesso modo in cui C ++ fa:

metodi / variabili / whatevers statici sono una cosa a livello di classe, NON una cosa a livello di oggetto. Per chiamare un metodo statico o accedere a una variabile statica, è necessario specificare (implicitamente o esplicitamente) la classe di cui si desidera accedere al membro statico. E puoi farlo senza MAI creare un oggetto del tipo di quella classe.

Se non ci sono oggetti, non ci può essere polimorfismo come esiste in queste lingue. Non ha senso perché tutti questi linguaggi fanno il polimorfismo basato sul tipo reale di un oggetto. Nessun oggetto, nessun polimorfismo.

    
risposta data 26.10.2014 - 14:51
fonte
0

C'è un modello di programmazione attuale chiamato Object Oriented, e al suo centro sono gli oggetti.

Sono supportati vari tipi di polimorfismo, anche se alcune persone amano discuterne. Ma il tipo principale e il più potente, è l'associazione dinamica della chiamata al metodo implementato dal tipo effettivo dell'oggetto target.

Diverse lingue forniscono diversi livelli di supporto per questo. Alcuni, come smalltalk, non garantiscono che il metodo sia implementato nella classe di destinazione, e così in fase di esecuzione è possibile ottenere un errore "messaggio non trovato" (smalltalk chiama metodi messaggi , genericamente parlando). Altri linguaggi strongmente tipizzati come C ++ e Java hanno regole di sintassi in base alle quali il compilatore può garantire che, dopo che il codice è stato compilato correttamente, la chiamata al metodo sarà da qualche parte appropriata.

Quindi potresti creare una lingua in cui il tipo di cosa desideri, può accadere. Semplicemente non sarebbe Java o C ++. Dovresti pensare a tutti i casi d'angolo per assicurarti che il codice funzioni sempre nel modo in cui lo definisci per funzionare nella definizione della tua lingua. Prova a leggere la specifica Java per avere un'idea di quanto questo deve essere fatto con attenzione.

Una soluzione a cui arrivano molte persone, invece di una nuova lingua, è Design Patterns. Vedi OO Design e Wikipedia . I modelli di progettazione forniscono soluzioni comuni ai problemi comuni e forniscono un vocabolario comune per la soluzione.

Vi imbatterete sempre in casi in cui "sarebbe bello se ..." e così tante persone producono soluzioni come la moltitudine di framework open-source esistenti. In confronto a un nuovo linguaggio conforme, un framework è relativamente facile da produrre e diffondere.

Quindi perché i membri statici non possono essere astratti e non implementare il polimorfismo? Perché non sarebbe orientato a oggetto e progettare un linguaggio per fare in modo che e convincere le persone ad accettarlo e usarlo è difficile.

    
risposta data 26.10.2014 - 16:00
fonte