Am'am lucrat cu furnizorii de servicii un pic echitabil în ultima vreme, și am dat peste o situație interesantă în care am vrut să avem o clasă abstractă care a avut un rezumat metoda statică. Am citit cateva posturi pe acest subiect, și este un fel de sens, dar există un frumos explicație clară?
Metodele statice nu sunt instanțiată ca atare, ele're doar disponibil fără un obiect de referință.
Un apel la o metodă statică se face prin numele clasei, nu printr-un obiect de referință, și Limba Intermediar (IL) codul de apel se va apela metoda abstractă prin numele clasei pe care a definit-o, nu neapărat numele de clasă de-ai folosit.
Lasă-mă să arăt un exemplu.
Cu codul de mai jos:
public class A
{
public static void Test()
{
}
}
public class B : A
{
}
Dacă suni B. Test, astfel:
class Program
{
static void Main(string[] args)
{
B.Test();
}
}
Apoi codul actual în interiorul metodă Principală este după cum urmează:
.entrypoint
.maxstack 8
L0000: nop
L0001: call void ConsoleApplication1.A::Test()
L0006: nop
L0007: ret
După cum puteți vedea, se face apel la A. Test, pentru că a fost O clasă care a definit-o, și să nu B. Test, chiar dacă puteți scrie codul asa.
Dacă ai avut clasa de tipuri, ca în Delphi, unde puteți face o variabilă se referă la un tip și nu un obiect, ar fi mai de folos pentru virtual și, astfel, rezumat metode statice (și, de asemenea, constructori), dar sunt't disponibile și, astfel, static apelurile sunt non-virtuale în .NET.
Mi-am dat seama ca IL designeri ar putea permite codul pentru a fi compilate pentru a apela B. Test, și de a rezolva apel la runtime, dar încă nu't fi virtual, ca tot ar trebui sa scriu un fel de nume de clasă acolo.
Metodele virtuale, și, astfel, cele abstracte, sunt utile numai atunci când te're folosind o variabilă care, la runtime, poate conține mai multe tipuri diferite de obiecte, și, astfel, doriți să apelați metoda potrivită pentru obiectul curent ai in variabila. Cu metode statice aveți nevoie pentru a merge printr-un nume de clasă, oricum, deci metoda exactă pentru a apela este cunoscut la compilare, deoarece aceasta poate't și a câștigat't se schimbe.
Astfel, virtual/rezumat metodele statice nu sunt disponibile în .NET.
Metodele statice nu pot fi moștenite sau înlocuite, și de aceea ele pot't fi rezumat. Deoarece metodele statice sunt definite pe tip, nu de exemplu, dintr-o clasă, acestea trebuie să fie numit în mod explicit pe acest tip. Deci, atunci când doriți pentru a apela o metoda pe un copil de clasa, aveți nevoie pentru a utiliza numele său să-l numesc. Acest lucru face ca moștenire irelevant.
Presupun că ai putea, pentru o clipă, moșteni metode statice. Imaginați-vă acest scenariu:
public static class Base
{
public static virtual int GetNumber() { return 5; }
}
public static class Child1 : Base
{
public static override int GetNumber() { return 1; }
}
public static class Child2 : Base
{
public static override int GetNumber() { return 2; }
}
Dacă te sun Baza.GetNumber(), metoda care s-ar fi numit? Care valoarea returnată? Sale destul de ușor pentru a vedea că, fără a crea instanțe de obiecte, moștenire este destul de greu. Metode abstracte fără moștenire sunt doar metode care don't au un corp, deci poate't fi numit.
Un alt respondent (McDowell) a spus că polimorfismul funcționează numai pentru cazuri de obiecte. Care ar trebui să fie calificat; există limbi care fac trata clase ca instanțe de un "Clasa" sau "Metaclass" tip. Aceste limbi de sprijin polimorfism atât pentru instanță și de clasa (statice) metode.
C#, Java și C++ înainte de aceasta, nu este o astfel de limbă; "statică" de cuvinte cheie este utilizat în mod explicit pentru a indica faptul că metoda este static legat mai degrabă decât dinamic/virtual.
Aici este o situație în care există cu siguranță o nevoie pentru moștenire pentru câmpuri statice și metode:
abstract class Animal
{
protected static string[] legs;
static Animal() {
legs=new string[0];
}
public static void printLegs()
{
foreach (string leg in legs) {
print(leg);
}
}
}
class Human: Animal
{
static Human() {
legs=new string[] {"left leg", "right leg"};
}
}
class Dog: Animal
{
static Dog() {
legs=new string[] {"left foreleg", "right foreleg", "left hindleg", "right hindleg"};
}
}
public static void main() {
Dog.printLegs();
Human.printLegs();
}
//what is the output?
//does each subclass get its own copy of the array "legs"?
Noi de fapt suprascrie metode statice (în delphi), l's un pic cam urât, dar funcționează foarte bine pentru nevoile noastre.
Putem folosi astfel de clase pot avea o listă de obiecte disponibile, fără clasă, de exemplu, avem o metoda care arata ca aceasta:
class function AvailableObjects: string; override;
begin
Result := 'Object1, Object2';
end;
L's urât, dar este necesar, în acest fel putem instantia doar ceea ce este necesar, în loc de a avea toate clasele instantianted doar pentru a căuta obiecte disponibile.
Acest lucru a fost un simplu exemplu, dar aplicația în sine este un client-server de aplicație care are toate clasele disponibile în doar un singur server, și mai mulți clienți care ar putea să nu nevoie de tot serverul are și nu va avea nevoie de un obiect instanță.
Deci, acest lucru este mult mai ușor să se mențină decât un alt server de aplicație pentru fiecare client.
Sper exemplu a fost clar.
Abstract metode sunt implicit virtuale. Rezumat metode necesită un exemplu, dar metodele statice nu au un exemplu. Deci, puteți avea o metodă statică într-o clasă abstractă, nu poate fi static, abstract (sau statice abstracte).