使用子类实例化的父对象有什么用处

时间:2011-07-02 16:52:02

标签: c# oop inheritance

请告诉我使用子类实例化的父对象是什么:

 public class A
    {
        public A()
        {
            Console.WriteLine("A");
        }
        public virtual void method()
        {
            Console.WriteLine("AM");
        }

    }
    public class B : A
    {
        public B()
        {
            Console.WriteLine("B");

        }
        public new void method()
        {
            Console.WriteLine("BM");

        }
        public void method1()
        {
            Console.WriteLine("BM1");
        }
    }

 class Program
    {
        static void Main(string[] args)
        {
            A obj = new B();// what is use of it?
            obj.method();              
            Console.Read();
        }
        private void methodP1()
        {

        }
    }
请告诉我有什么用处 父obj = new Child(); 因为我只能调用可能使用的父类的公共方法 父obj = new Parent();

是否可能:Child obj = new Parent()?

8 个答案:

答案 0 :(得分:9)

  

请告诉我Parent的用途   obj = new Child();因为我只能   只调用父母的公共方法   可以使用Parent的类   obj = new Parent();

这是polymorphism的基础:想象一下,你有几个继承自你父类的子类。您希望通过父类中定义的接口/方法使用所有这些子类,而不必担心每个子类中的实现细节(每个子类可能做不同的事情,但具有相同的整体语义)。

这是可能的,因为子类与其父类具有IS A关系,因为子类继承自父类。

答案 1 :(得分:6)

在您的示例中,B 是-a A,但A 不是 B.

当使用对B的引用的代码只能理解(或需要理解)A的类型时,以上是有用的.B是A的特化。想象一下(伪代码) )

Shape s;
if (x == 1) {
  s = new Square();
}
else {
  s = new Triangle();
}
// following code knows only about Shapes
s.draw();
s.calculateArea();

以下代码不需要知道s是正方形还是三角形,只是它是一个形状。有什么用?如果你打电话给s.draw(),形状本身就决定了它的外观。调用它的代码不知道或不关心。

这是面向对象编程的关键点。 要求对象为您做事,而不是确定自己需要什么

请注意,使用此示例时,您的最终问题并不直观。

  

Shape s = new Square(); //很好

VS

  

Square s = new Shape(); //你可以实例化一个“形状”,为什么你认为它是一个正方形?

答案 2 :(得分:6)

BrokenGlass的答案是正确的。但是,根据您是将obj声明为A还是B,您的示例会有不同的行为。

A obj = new B();的情况下,程序将输出A B AM,因为编译器链接到虚拟方法A.method,然后B类继承。

B obj = new B();的情况下,程序输出A B BM,因为编译器被指示使用 new 方法B.method()。

如果B.method()被声明为public override void method(),则输出将始终为A B BM,无论obj是声明为A型还是B型。

因此,您的示例在经典意义上不显示多态性,因为调用类型B的实例的方法取决于实例所分配的变量的类型。这个可以使调试变得有趣和有趣。

答案 3 :(得分:2)

您将使用多态的原因是您可以将更具体的对象传递给只需要更通用对象的实体。接收对象的实体仅关注公开的公共接口,而不关心该接口中的方法如何执行的细节。这是一个简单的类层次结构:

public class Animal
{
    public virtual string GetFood()
    {
        return "Food";         
    }
}

public class Monkey : Animal
{
    public override string GetFood()
    {
        return "Bananas";
    }
}

public class Cow : Animal
{
    public override string GetFood()
    {
        return "Grass";
    }
}

以下是您可以使用多态的方法:

class Program
{
    static void Main(string[] args)
    {
        Animal[] animalArray = { new Monkey(), new Cow() };
        foreach (Animal a in animalArray) {
            WhatDoIEat(a); // Prints "Bananas", then "Grass"
        }         
    }

    static void WhatDoIEat(Animal a)
    {
        Console.WriteLine(a.GetFood());
    }
}

答案 4 :(得分:1)

如果必须仅使用父类的方法,则可以继续并实例化它。子类的对象是在保持父类完整的同时向父类添加功能。通过子实例化父级而不进一步使用子功能是没有意义的。

答案 5 :(得分:1)

在像你这样的简单例子中没有用,因为变量的使用范围是有限的。但重要的是要理解,.NET变量的类型是静态的,在编译时是已知的,即使obj保持对Child类的引用,它仍然被键入为Parent

如果您的方法需要Parent,则可以将obj(类型为Child)传递给它(它的行为仍然像Child) - 这是由Child类型引用Parent的示例。

Child obj = new Parent()是不可能的,Parent不是Child,编译器不允许您将对象分配给不兼容类型的变量。

答案 6 :(得分:0)

假设您有一个名为Animal和Child类的父类,名为Dog,Cat和Lizard。每个类都有一个方法调用makeSound()。然后,当您说Animal a1 = new Dog();Animal a2 = new Cat()时,a1.makeSound()会吠叫,a2.makeSound()会喵喵叫。

此行为的技术术语称为多态。它对代码重用很有用。您只需要为有兴趣的动物makeSound()的应用程序编写一次代码,而不是为每种动物类型单独编写代码。

多态的另一个用途是将代码的实现隐藏在其他用户之外。例如,您可以向其他用户显示您正在使用List,然后您可以选择将List实现为LinkedList或ArrayList。您也可以选择LinkedList,然后在以后切换到ArrayList而不影响您的用户。

您也不能说Dog d = new Animal()因为狗是动物但动物不一定是狗。

答案 7 :(得分:0)

当你知道继承的类的公共特性,当你不知道确切的孩子时,你可以将数据放在父类上,每当你知道子类时,你可以在其上分配这些值。