2017-05-07 130 views
0

我目前正在學習用德語書籍「SchrödingerProgrammiert C#」編程的C#語言,並在頁面156有一個代碼示例。問題是:我不明白爲什麼我在第二種方法中使用靜態而不是第一種方法。對象中的靜態方法和非靜態方法之間的區別

Person類

class Person 
{ 
    public string Name { get; set; } 
    public float WalkedKm 
    { 
     get 
     { 
      return this.Footsteps * 0.75f/1000.0f; 
     } 
    } 
    public float Weight { get; set; } 
    public int Footsteps { get; private set; } 

    public void Walk (int Footsteps) 
    { 
     if (Footsteps > -1) 
      this.Footsteps += Footsteps; 
    } 

    public static float AverageWalkedKm(Person[] persons) 
    { 
     int amount = persons.Length; 
     float walkSum = 0; 
     foreach (Person p in persons) 
      walkSum += p.WalkedKm; 
     return walkSum/(float)amount; 
    } 
} 

在main方法

Person p1 = new Person(); 
Person p2 = new Person(); 
p1.Name = "Schrödinger"; 
p2.Name = "Schrödingers Girlfriend"; 
p1.Walk(1500); 
p2.Walk(1500); 
p2.Walk(2100); 
Person[] person = new Person[] { p1, p2 }; 
Console.WriteLine("Schrödingers steps: {0}. km {1}", p1.Footsteps, p1.WalkedKm); 
Console.WriteLine("Her steps: {0}. km {1}", p2.Footsteps, p2.WalkedKm); 
float average = Person.AverageWalkedKm(person); 
Console.WriteLine("Average: {0}km", average); 
Console.ReadKey(); 

請幫助我理解上的差異!

+0

WalkedKm沒有被聲明爲靜態的,因爲它需要訪問它所調用的類的實例的狀態(this.Footsteps)。 AverageWalkedKm可以是靜態的,因爲它不使用類中存儲的任何狀態。靜態被認爲是可取的,因爲你不需要創建它所連接的類的實例,或者使用與其內部邏輯鬆散耦合的方法來處理它。 –

回答

0

float AverageWalkedKm(Person[] persons)可以是靜態的,因爲它不試圖訪問類的任何實例成員(字段,屬性或方法)。

void Walk (int Footsteps)不能是靜態的,因爲它確實存取實例類的成員。 (即,Footsteps財產。)

注:實例成員=非靜態成員。

編輯

所以,你的對象,在AverageWalkedKm()Person[] persons參數的數據類型Person的,所以它似乎你它正在訪問實例成員。

嗯,是的,它是訪問實例成員,但不是它自己的實例。它被賦予與它一起工作的實例。所以,這個方法可以屬於完全不同的類,它仍然可以工作,不會改變,因爲它被調用的實例爲Person。當我們說一個實例方法能夠訪問實例成員時,我們的意思是自己的實例,如this.member或甚至沒有this.,因爲它是可選的。

+0

您應該使用以下內容更正您的句子:_「該類別的所有成員字段,屬性或方法不是靜態的_」或「不屬於特定實例的_」或類似內容。 –

+0

@MassimilianoKraus好吧,你是對的。 –

+0

好的。但在AverageWalkedKm方法參數** Person [] persons **中有一個數組「Person」,是不是試圖訪問任何實例成員? –

0

因爲你使用的足跡變量,它不是一成不變的

0

當您不需要(或想要)需要該類的對象實例時,可以使用靜態方法。在您的示例中,無論您是否創建了Person類的對象實例,都可以調用Person.AverageWalkedKm方法。但是,由於Walk方法引用實例變量(Footsteps),因此它不能是靜態的:您必須先創建Person類的實例(在您的示例中爲p1和p2),然後使用這些實例來調用Walk方法。

相關問題