首页 > 解决方案 > 重载方法——引用和实例化对象的区别

问题描述

在上面的代码片段中,我有一个基类 Shape 和两个派生类,Rectangle以及Triangle. 我实例化它们,但对于一个Triangle对象,我使用他的基类的引用类型。
所以现在当我调用一个方法时calculate(),它会更喜欢调用采用基类参数的方法。

这样做的目的是什么?

我正在创建Triangle对象而不是Shape对象我只是使用基类的引用。我的另一个问题是它们与使用基类的引用和从派生而不是使用派生引用实例化对象是否有任何其他区别?

public static void Main(string[] args)
{
    Point tc = new Point(3, 4);
    Point rc = new Point(7, 5);

    Shape shape = new Triangle(tc, 4, 4, 4);

    calculate(shape);
}

public static void calculate(Shape shape) <<-- new Triangle()  with base class ref will came here.
{
    Console.WriteLine("shape");
}

public static void calculate(Rectangle rectangle) 
{
    Console.WriteLine("rectangle");
}

public static void calculate(Triangle triangle) <<-- new Triangle() using triangle ref will came here.
{
    Console.WriteLine("triangle");
}

标签: c#polymorphismoverloading

解决方案


第一个问题:所以现在当我调用方法 calculate() 时,它会更喜欢调用采用基类参数的方法。这样做的目的是什么?

答:怎么可能是其他方式?编译器无法确定对象的“实际”类型,因为这只能在运行时真正知道。您有责任使用“反射”(例如 GetType() 和 typeof() )将该父对象(形状)转换为其子对象(三角形),然后将其作为参数传递。如果它以任何其他方式工作,您将无法正确实现以下方法。

 public foo(object var1){
     // Test for var1's type and perform a operation
 }

第二个问题:它们与使用基类的引用和从派生而不是使用派生引用实例化对象是否有任何其他区别?

答:在内存中,引用始终指向相同的数据,但上下文会发生变化。这意味着对象是哪种类型的对象(子对象或父对象)决定了可以访问哪些字段/方法。将对象转换为哪种类型不会改变实际存储在堆上的内容,而是会改变您可以访问的内容。这从下面的代码片段中得到了证明。

    public class Parent {
        public int var1 = 1;
    }

    public class Child : Parent {
        public int var2 = 2;
    }

    public void foo () {
        Parent theObject = new Child();
        int num1 = theObject.var1;          // Valid
        int num2 = theObject.var2;          // Invalid
        int num3 = ((Child)theObject).var2; // Valid
    }

推荐阅读