Quali linguaggi popolari orientati agli oggetti supportano i metodi readonly?

6

Ho pensato che molti linguaggi orientati agli oggetti hanno una parola chiave riservata per i metodi che non modificano lo stato di un oggetto. Questi metodi hanno spesso nomi che iniziano con get . AFAIK un "getter" è sempre correlato a un singolo attributo dell'oggetto e "accessor" è troppo generico, quindi "readonly" può essere il termine giusto per questo tipo di metodi (?). Per fare un esempio:

object Timespan {
    attribute start
    attribute end

    // getter, not changing the state
    readonly method getStart    { return start } 
    readonly method getEnd      { return end }

    // also not changing the state
    readonly method getDuration { return ( end - start ) }
}

Il compilatore / interprete dovrebbe verificare che i metodi readonly non abbiano effetti collaterali modificando gli attributi dell'oggetto. Mi chiedo perché questa caratteristica del linguaggio non sia più comune - solo nominare un metodo getFoo non garantisce che non modificherà l'oggetto.

    
posta Jakob 11.10.2011 - 23:49
fonte

4 risposte

20

In C ++ puoi dichiarare le funzioni membro const . Tali metodi non possono modificare lo stato dell'oggetto (nemmeno potenzialmente, cioè non possono chiamare metodi non-const dello stesso oggetto), e ciò è assicurato dal compilatore.

    
risposta data 11.10.2011 - 23:54
fonte
2

Quello che vuoi è const di C ++. In genere lo trovo estremamente utile e non capisco perché altre lingue non ce l'abbiano, ma non lo fanno. L'unica altra lingua che conosco per avere qualcosa di simile è D, ma le differenze nella semantica, pur rendendola più utile all'ottimizzazione, la rendono meno utile per limitare le interfacce.

In altri linguaggi come Java e C #, l'unica cosa che puoi fare è creare un'interfaccia solo con i metodi costanti, implementarla nell'oggetto e downcast su quell'interfaccia se vuoi passare l'oggetto ma non permetterne la modifica. A differenza del C ++, non si otterrà il compilatore verificando che i metodi siano effettivamente costanti.

Sebbene l'interfaccia serva al fine ultimo di essere in grado di passare l'oggetto per riferimento e tuttavia l'altro codice non lo modificherà, l'uso di un'interfaccia implica sempre l'overhead delle chiamate virtuali mentre in C ++ è un tempo di compilazione relazione.

    
risposta data 12.10.2011 - 08:48
fonte
2

Un metodo che non ha alcun effetto osservabile sullo stato dell'oggetto è comunemente noto come metodo "puro" . La parola chiave qui è osservabile. Nel caso di lazy instantiation o caching, questi effetti non sarebbero necessariamente osservabili dal consumatore, quindi il metodo sarebbe comunque considerato un metodo puro.

In C # (e in altri linguaggi che supportano i metadati), puoi dichiarare un attributo su un metodo che lo identifica come puro, e gli strumenti di analisi statici possono essere usati per avvisarti se non lo sono (o più utilmente, se regredisce dall'essere puro).

vedi: link

    
risposta data 12.10.2011 - 10:32
fonte
1

Python:

@property
def foo():
    return self.__foo

C #:

class Foo
{
    public int bar()
    {
        get
        {
            return 1;
        }
    }
}

È vero che l'esempio Python non tecnicamente rende le cose in sola lettura, ma è "supportato". Un meccanismo per comunicare ad altri programmatori che il metodo è di sola lettura conta come supporto. E no, non deve essere semplicemente un getter banale che restituisce solo un campo istanza.

    
risposta data 12.10.2011 - 00:31
fonte

Leggi altre domande sui tag