它是什麼歸結到,當訪問一個字段,你可以立即訪問它,因爲它是立即鍵入。在這種情況下,當您將某個字段鍵入爲界面:IShoulders
時,您只能直接訪問該界面定義的任何屬性/方法。當您訪問定義爲實現相同接口的類的字段時,定義並訪問爲RightHand
的新字段不僅提供對由IShoulders
定義的屬性/方法的訪問,還提供對RightHand
類定義的擴展屬性/方法的訪問。
有了您的定義,有沒有真正的區別就在這裏一邊從值move()
打印出來,而是採取了以下變化:
public class RightHand implements IShoulders {
public void move(){
System.out.println("Move Right Hand");
}
public void Gesture()
{
System.out.println("Make a gesture with Right Hand");
}
}
新Gesture
方法只能被定義爲RightHand
現場訪問,它不會存在於僅定義爲IShoulders
的字段中,即使您使用new RightHand()
分配字段,也需要將該字段框或轉換爲RightHand
以訪問新方法。
鑑於上述RightHand
類的定義,請嘗試以下操作:
IShoulders shoulder = new RightHand();
shoulder.move(); // this will work fine...
shoulder.Gesture(); // this will not be possible as "Gesture()" does not exist on IShoulders.
((RightHand)shoulder).Gesture(); // this will work after casting shoulder as RightHand
// since the underlying object is actually a RightHand.
然後嘗試以下操作:
RightHand rhand = new RightHand();
rhand.move(); // again, this works fine...
rhand.Gesture(); // this now works fine too..
更進一步,該接口是您實現它的任何類合同。它只是說如果一個類實現了一個接口,它必須實現該接口中的所有內容。但是,它沒有說什麼,它應該如何實施。所以,只要類實現了接口的結構,那些實現的內容就可以完全爲每個類定製。
實現接口的替代方法是使用子類創建派生類。這看起來類似於實現接口,但是基類已經實現了屬性和方法。除非你不用virtual
來修飾它們,否則它們可以被覆蓋,或者在另一個繼承層次上,你可以覆蓋並使用final
修飾。
我;對不起,但讓我們調一下,因爲它仍然有點混亂。 當我寫IShoulder rightHand或RightHand rightHand i; m在創建它之前定義了 對象的類型?另外我一直想問 爲什麼我們需要定義一個類型,如果我們仍然使用新的關鍵字 就像我們對任何其他對象如集合所做的那樣?列表<> mylist = 新列表<>以及如何解決這個口頭? like object rightHand class RightHand封裝RightHand/IShoulder?糾正我,如果IAM 錯誤 - eersteam
當然,這樣的輸入變量 - 這允許編譯器(和程序員,對於這個問題),以強烈的定義可以用什麼,以及如何可以用在關心對象/價值。一個簡單的例子將是一個函數:
public string HyphenateTwoWords(string word1, string word2)
{
return string.Format("{0}-{1}", word1, word2);
}
上述函數有兩個string
參數和在它們之間具有連字符一起加入他們。如果參數未輸入爲string
,則可能傳入任何內容,結果在某些情況下可能只是錯誤,或者在其他情況下引發異常。由於它們被定義爲string
,因此string.Format()
調用沒有任何問題。現在
,在C#和其他語言,你實際上可以定義一般使用var
一個字段/變量,例如:
List<string> myStringList = new List<string>();
myStringList.Add("Test1");
myStringList.Add("Test2");
myStringList.Add("Test3");
foreach(var item in myStringList)
Console.WriteLine(item);
這讓編譯器推斷出的item
的實際類型是基於什麼分配給它。但是,在大多數情況下,您不會真的想使用var
。如果沒有其他原因,最好明確地鍵入你的變量,可讀性。查看變量的類型很容易,尤其是當您使用由多個開發人員維護的代碼時。此外,顯式輸入一個變量可以確保按預期使用該變量,否則會引發可處理的異常,或者在構建解決方案時編譯器會拋出錯誤或警告。
現在,關於上述的評論:
...如何將我知道,如果它的左手還是右手? 在我的例子中,雙手不是肩膀,而是手應該是 附加到應該因爲肩膀使他們能夠移動。 那麼你會如何實現呢? - eersteam
讓我們設計一些接口和類來說明它們的用途,我會作出一些改變/添加到你有什麼已經所有這些應該是相當直正向在AddLegs()
方法看看在Body
類看看LeftLeg
也是如此。
public class BodyConstructor
{
public interface IBody
{
int Age { get; set; }
string Species { get; set; }
BodyPartGroup Head { get; set; }
BodyPartGroup Thorax { get; set; }
BodyPartGroup Abdomen { get; set; }
BodyPartGroup Pelvis { get; set; }
}
public interface IBodyPartGroup
{
BodyPartGroupType Type { get; set; }
List<IBodyPart> BodyParts { get; set; }
}
public interface IBodyPart
{
LateralDirection LateralOrientation { get; set; }
string Name { get; set; }
List<IBodyPart> SubParts { get; set; }
void Move();
}
public enum BodyPartGroupType
{
Head = 1,
Thorax = 2,
Abdomen = 3,
Pelvis = 4,
}
public enum LateralDirection
{
Central = 0,
Right = 1,
Left = 2,
}
public class Body : IBody
{
public Body()
{
Head = new BodyPartGroup(BodyPartGroupType.Head);
Thorax = new BodyPartGroup(BodyPartGroupType.Thorax);
Abdomen = new BodyPartGroup(BodyPartGroupType.Abdomen);
Pelvis = new BodyPartGroup(BodyPartGroupType.Pelvis);
}
public Body(int age, string species)
: this()
{
Age = age;
Species = species;
}
public int Age { get; set; }
public string Species { get; set; }
public BodyPartGroup Head { get; set; }
public BodyPartGroup Thorax { get; set; }
public BodyPartGroup Abdomen { get; set; }
public BodyPartGroup Pelvis { get; set; }
public void AddLimbs()
{
AddArms();
AddLegs();
}
public void AddArms()
{
// Individual segments for the left arm
BodyPart leftShoulder = new BodyPart("Left Shoulder", LateralDirection.Left);
BodyPart leftArm = new BodyPart("Left Arm", LateralDirection.Left);
BodyPart leftHand = new BodyPart("Left Hand", LateralDirection.Left);
leftArm.SubParts.Add(leftHand);
leftShoulder.SubParts.Add(leftArm);
// Individual segments for the right arm
BodyPart rightShoulder = new BodyPart("Right Shoulder", LateralDirection.Right);
BodyPart rightArm = new BodyPart("Right Arm", LateralDirection.Right);
BodyPart rightHand = new BodyPart("Right Hand", LateralDirection.Right);
rightArm.SubParts.Add(rightHand);
rightShoulder.SubParts.Add(rightArm);
// Add arms to thorax
Thorax.BodyParts.Add(rightShoulder);
Thorax.BodyParts.Add(leftShoulder);
}
public void AddLegs()
{
// Individual segments for the left leg
BodyPart leftHip = new BodyPart("Left Hip", LateralDirection.Left);
LeftLeg leftLeg = new LeftLeg(); // Here we use the LeftLeg class instead, which inherits BodyPart
BodyPart leftFoot = new BodyPart("Left Foot", LateralDirection.Left);
leftLeg.SubParts.Add(leftFoot);
leftHip.SubParts.Add(leftLeg);
//Individual segments for the right leg
BodyPart rightHip = new BodyPart("Right Hip", LateralDirection.Right);
BodyPart rightLeg = new BodyPart("Right Leg", LateralDirection.Right);
BodyPart rightFoot = new BodyPart("Right Foot", LateralDirection.Right);
rightLeg.SubParts.Add(rightFoot);
rightHip.SubParts.Add(rightLeg);
// Add legs to pelvis
Pelvis.BodyParts.Add(leftHip);
Pelvis.BodyParts.Add(rightHip);
}
}
public class BodyPartGroup : IBodyPartGroup
{
public BodyPartGroup()
{
BodyParts = new List<IBodyPart>();
}
public BodyPartGroup(BodyPartGroupType type)
: this()
{
this.Type = type;
}
public BodyPartGroupType Type { get; set; }
public List<IBodyPart> BodyParts { get; set; }
}
public class BodyPart : IBodyPart
{
public BodyPart()
{
SubParts = new List<IBodyPart>();
}
public BodyPart(string name, LateralDirection orientation)
: this()
{
Name = name;
LateralOrientation = orientation;
}
// Location of body part: Left, Central, Right
public LateralDirection LateralOrientation { get; set; }
public string Name { get; set; }
public List<IBodyPart> SubParts { get; set; }
public virtual void Move()
{
// Common body part movement code.
}
}
public class LeftLeg : BodyPart
{
public LeftLeg()
{
Name = "Left Leg";
LateralOrientation = LateralDirection.Left;
}
public override void Move()
{
// Custom left leg move code
base.Move(); // Call base BodyPart.Move();
}
}
}
我;對不起,但讓我們調一下,因爲它仍然有點混亂。當我寫IShoulder rightHand或RightHand rightHand i; m在創建它之前定義對象的類型?另外,我總是想問,爲什麼我們需要定義一個類型,如果我們正在使用new關鍵字,就像我們對任何其他對象如集合所做的那樣?列表<> mylist =新列表<>以及如何解決這個口頭?像RightHand類的對象rightHand封裝RightHand/IShoulder?糾正我,如果我錯了 – eersteam
我已經更新了我的答案與關於輸入字段/變量的更多信息。我會盡量給你一些解釋,但是,這實際上是一個非常廣泛的主題,對於你在一本關於一般OOP約定和實踐的書或教程中閱讀可能會更好。 – gmiley
對於「var」,我不太贊同。有些情況下它可能會隱藏你的類型,但是在大多數類型被聲明在賦值語句右邊的情況下,使用var可以提高可讀性和可維護性。 – bodangly