2014-02-28 85 views
0

我有幾個面向對象的混淆,我無法擺脫。幾個面向對象的混淆在創建對象

/// program 1 
    class Epos 
    { 

    } 
    class Epos2 : Epos 
    { 
     Epos obj = new Epos2(); 
     Epos2 obj1 = new Epos();// Why it fails at compile time 
    } 
    /// program 2 

    class baseclass 
    { 
     protected baseclass() { } 
    } 
    class Epos : baseclass 
    { 
     Epos e = new Epos(); 
     baseclass b = new baseclass();// Why it fails as per the protected definition it should be accessible in derive class. 
    } 
+2

'Epos'不是'Epos2'。 – SLaks

+3

每隻狗都是動物'動物a =新的狗();'但不是每個動物都是狗'狗d =新動物()' –

+1

受保護的構造函數意味着你只能生成一個基類的子類 – Decoy

回答

2

這是一個祖先/後代關係的實例化。

class Dog : Anima{} 
class Cat : Animal{} 

Animal dog = new Dog(); //Correct 
Animal cat=new Cat(); //Correct 
Dog d=cat; //Incorrect 

每隻狗都是動物,每隻貓都是動物,但不是每隻動物都可以是狗或貓。

但是你可以投你的基礎對象引用子類型,如果是同一類型:

Dog d=(Dog)dog; 

而且,繼承「是-A」樣的關係也被稱爲推廣。這意味着繼承類是「祖先類」,但不一定是反過來,即「狗」是「動物」,但不一定是相反的。

您還可以看到下面的例子:

class Animal{} 
class Dog : Animal {} 
class Labrador : Dog{} 
class Husky : Dog{} 

現在,如果我說,我有一隻狗,我會稱他爲動物,這將永遠是正確的。事實上,我有一隻哈士奇,我可以把它稱爲一隻總是正確的狗或動物。 但是,如果我說,我有一隻狗,我會稱他爲拉布拉多犬,可能不正確。如果我有赫斯基怎麼辦?

編輯:只是給你一個真實世界的例子。

class Person 
{ 
    string Name{ get; set; } 
} 

class Employee : Person 
{ 
    string Id{ get; set; } 
} 

現在,我可以這樣做:

Person p = new Employee(); 
Console.WriteLine("Name is: {0}", p.Name); 

但我可以做的:

Employee e = new Person(); 
Console.WriteLine("Employee Id is: {0}", e.Id); 

上面的語句將是有缺陷的COS對象是類型的人,並沒有屬性Id,儘管引用是Employee類型的。

但我仍然可以這樣做:

Person p = new Employee(); 
Console.WriteLine("Name is: {0}", p.Name); 
Console.WriteLine("Id is: {0}", ((Employee)p).Id); 

上述類型轉換是可能的,因爲refernce即,p型是人的,但實際的固有目的是Employee類型。

請注意,在進行類型轉換時,編譯器只在編譯時檢查繼承關係,而不檢查實際類型。實際類型在運行時檢查。例如。

class Teacher:Person 
{} 

現在,如果你做到以下幾點:

Person p = new Teacher(); 
Employee e = (Employee)p; 

上面的代碼不會產生編譯器警告,但會在運行時失敗。

+0

好吧,讓我通過..我會有任何疑問,我會問你.. – NoviceToDotNet

1

這是一個較好的例子來說明的擴展類

class Animal 
{ 

} 
class Dog : Animal 
{ 
    Animal obj = new Dog(); // Allowed 
    Dog obj1 = new Animal(); // Not allowed 
} 
+0

但是,爲什麼我沒有得到記憶分配..在這些話是真的。 – NoviceToDotNet

+0

你的問題沒有任何意義。 – StephenH

1

Epos2是從Eposinherited,所以

Epos obj = new Epos2(); 

線將創建一個新對象Epos2convert它變成一個Epos隱含。

Epos不是Epos2,也沒有從它繼承,所以的

Epos2 obj1 = new Epos(); 

線路出現故障時,它應失敗,閱讀更多關於面向對象的編程理解它。

baseclass b = new baseclass(); 

失敗的線,因爲在Epos我們不再談論class命名baseclass,我們正在談論Epos。另外,我可以建議你在constructor或在構造函數中調用的方法初始化嗎?這段代碼很糟糕。

+0

你是什麼意思,你是否在構造函數中初始化或在構造函數中調用的方法? – NoviceToDotNet

+1

通過執行初始化或在構造函數中調用的方法,我的意思是將您的初始化代碼寫入構造函數的塊中,或者在構造函數的塊中直接或傳遞調用的方法的塊內部寫入。 –

+0

是的,我也這麼做。 – NoviceToDotNet

1

這是你正在嘗試做什麼?

public class Epos 
{ 
    protected Epos(int x) { this.X=x; } 
    public Epos(Epos other) { this.X=other.X; } 
    public int X { get; protected set; } 
} 

public class Epos2 : Epos 
{ 
    public Epos2(int x, string s) : base(x) { this.S=s; } 
    public Epos2(Epos other, string s) : base(other) { this.S=s; } 
    public Epos2(Epos2 other) : base(other) { this.S=other.S; } 
    public string S { get; protected set; } 
} 

// call as: 
// var A = new Epos2(1,"A"); 
// var b = new Epos(2); 
// var B = new Epos2(b, "B");