在创建对象时出现一些面向对象的混淆

时间:2014-02-28 14:07:52

标签: c#

我有一些面向对象的混乱,我无法摆脱。

/// 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.
    }

4 个答案:

答案 0 :(得分: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;

此外,继承是'is-a'这种关系,也称为泛化。这意味着,继承类'是'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);

上述陈述是有缺陷的,因为对象属于person类型,并且它没有属性Id,尽管引用的类型为Employee。

但我仍然可以这样做:

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

上面的类型转换是可能的,因为引用即p是Person类型,但实际的固有对象是Employee类型。

请注意,在类型转换期间,编译器仅在编译期间检查继承关系,而不是实际类型。在运行时检查实际类型。例如

class Teacher:Person
{}

现在,如果您执行以下操作:

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

上述代码不会生成编译器警告,但会在运行时失败。

答案 1 :(得分:1)

这是演示扩展类实例化的更好示例

class Animal
{

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

答案 2 :(得分:1)

Epos2来自inherited的{​​{1}},所以

的行
Epos

会隐式创建一个新的Epos obj = new Epos2(); 对象,并将Epos2创建为convert

Epos不是Epos,也不是从中继承的,因此

Epos2

失败,它应该失败,阅读更多关于面向对象的编程以理解它。

Epos2 obj1 = new Epos();

失败,因为在baseclass b = new baseclass(); 我们不再谈论名为Epos的{​​{1}},我们正在谈论class。另外,我可以建议您在baseclass或构造函数中调用的方法中进行初始化吗?这段代码很难看。

答案 3 :(得分: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");