Esistono metodi di prima classe?

2

Ok, so che le funzioni di prima classe sono interessanti, le chiusure ancora migliori, ecc. Ma esiste un linguaggio con metodi di prima classe?

Nella mia mente, vedo un metodo di prima classe come un "oggetto" che ha sia un puntatore a funzione che un puntatore a un'istanza specifica della classe / oggetto, ma l'implementazione non ha importanza. Voglio solo sapere se c'è un qualsiasi linguaggio che li usa.

E come bonus, come sono stati implementati?

    
posta Gavin Howard 23.08.2014 - 09:18
fonte

5 risposte

4

Nel tipico linguaggio OO, i metodi appartengono agli oggetti. Se i metodi fossero essi stessi oggetti, allora questi oggetti avrebbero ovviamente dei metodi. Ma anche questi sono oggetti, quindi hanno metodi. Quali sono gli oggetti che hanno metodi che sono oggetti che hanno metodi che sono oggetti che hanno metodi ...

Ci sono modi per affrontare questo tipo di ricorsione, ma il modo usuale per affrontare questo problema è non avere metodi di prima classe.

In Ruby, ad esempio, ci sono metodi riflessivi che forniscono oggetti proxy per i metodi (quegli oggetti proxy sono di classe Method ), ma quelli non sono i metodi stessi, sono solo proxy che rappresentano i metodi.

Tuttavia, in Self, gli oggetti non hanno metodi, hanno solo slot ( campi in Java-lingo, variabili di istanza in Rubino). L'invio di un messaggio a un oggetto non richiama un metodo, attiva uno slot. Le slot possono essere passive o attive. Gli slot passivi restituiscono semplicemente l'oggetto a cui fanno riferimento, gli slot attivi eseguono l'oggetto a cui fanno riferimento. Quindi, i metodi sono oggetti di prima classe che vengono semplicemente assegnati agli slot attivi. (Se hai usato ECMAScript, potresti riconoscere qui la sua eredità di Self. ECMAScript non distingue tra slot passivi e attivi, ma usa una sintassi speciale per eseguire l'oggetto restituito dalla proprietà.)

    
risposta data 23.08.2014 - 10:23
fonte
2

In Python, i metodi sono campi regolari, ma richiamabili. Inoltre hanno un parametro self che è esplicitamente dichiarato, ma passato implicitamente; sebbene tu possa invocare qualsiasi metodo sull'oggetto classe, passando esplicitamente un'istanza.

class A:
    def __init__(self, val):
        self._val = val
    def fun(self):
        print(self._val)

def invoke(f):
   f()

def invoke_with_param(f, par):
    f(par)

x1 = A(1)
x2 = A(2)

invoke(x1.fun)
invoke(x1.fun)
A.fun(x1)
A.fun(x2)
invoke_with_param(A.fun, x1)
# etc.
    
risposta data 23.08.2014 - 11:22
fonte
2

Sì, in javascript. Questo perché in javascript i metodi sono funzioni e le funzioni sono oggetti a tutti gli effetti.

Esempio:

// Here's a "class" with method foo.
// Note that javascript don't really have classes,
// we use constructors instead:
function FooTeNator () {
    this.text = "foo";
}
FooTeNator.prototype.foo = function () {return this.text}

Nota la prima cosa interessante: i metodi sono solo funzioni di prima classe assegnate al prototipo del nostro costruttore.

Chiamata al metodo normale:

var foomatic = new FooTeNator();
foomatic.foo(); // returns "foo"

Ridefinire un nuovo metodo dopo aver creato l'oggetto:

var foomatic = new FooTeNator();
foomatic.foo = function () { return "" }
foomatic.foo(); // returns empty string

Lasciando che un altro oggetto prenda in prestito il nostro metodo:

var foomatic = new FooTeNator();
var other_object = {}; // {} is a plain object in object literal syntax
other_object.text = "bar";
other_object.foo = foomatic.foo;
other_object.foo(); // returns "bar"

Lasciando che un altro oggetto prenda in prestito il nostro metodo dal nostro costruttore:

var other_object = {text : "bar"};
other_object.foo = FooTeNator.prototype.foo;
other_object.foo(); // returns "bar"

Chiamando il nostro metodo mentre riassegniamo temporaneamente il valore di this al suo interno a un altro oggetto:

var foomatic = new FooTeNator();
var other_object = {text : "bar"};
foomatic.foo.call(other_object); // returns "bar"

Penso che si qualifichi come metodo di prima classe. Certo, questa è solo una funzione di prima classe. Ma per quanto riguarda la funzione OO, la funzione non è una funzione regolare perché in essa viene indicato this .

Nota a margine:

Javascript ha uno strano concetto di this . Anche le funzioni regolari possono fare riferimento a this al di fuori degli oggetti. Quando non è associato a nessun oggetto, javascript associa this all'ambito globale o all'oggetto DOM o indefinito a seconda delle circostanze.

Lato, nota a margine:

Quando ho detto che le funzioni sono oggetti in javascript significa davvero cosa significa. Le funzioni (quindi i metodi) hanno un costruttore, la funzione Function . Anche le funzioni / i metodi possono avere metodi:

// Creating a method using the Function constructor
var my_object = {
    strange_method : new Function('x','return x');
}
// Assigning a method to our method:
my_object.strange_method.sub_method = function () {return 'HA!'};
    
risposta data 23.08.2014 - 11:21
fonte
1

C ++ 11 lambda:

struct Foo{
    int bar(){
        return 42;
    }
};

Foo f;
auto methodobject = [&]{ return f.bar(); };
int i = methodobject(); //calls f.bar

Lambdas è implementato come classi regolari con gli oggetti catturati (in questo caso Foo &f ) come membri e un auto operator (){/*whatever is in the lambda declaration*/} . Con un po 'più di digitazione puoi creare una classe regolare che esegue la cattura e la chiamata e puoi cambiare l'oggetto e il metodo da chiamare in fase di runtime.

    
risposta data 23.08.2014 - 10:48
fonte
1

Le funzioni in JavaScript sono cittadini di prima classe (oggetti con metodi). Non ci sono metodi di per sé, ma ogni funzione può essere invocata come metodo su qualsiasi oggetto. Le funzioni possono anche essere assegnate ai campi e invocate in sintassi orientata agli oggetti come in c ++.

var func = function(arg) {
  this.field = arg;
}

func.apply(null, ["value0"]); // 'func' invoked as a free function
// window.field == "value0"

var obj = {};
func.apply(obj, ["value1"]); // 'func' invoked as a method of 'obj'
// obj.field == "value1"

obj.method = func;
obj.method("value2")
// obj.field == "value2"
    
risposta data 23.08.2014 - 11:10
fonte

Leggi altre domande sui tag