Перегруженные методы - разница между ссылками и объектами - PullRequest
3 голосов
/ 24 июня 2019

В приведенном выше фрагменте кода у меня есть базовый класс 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");
}

Ответы [ 2 ]

3 голосов
/ 24 июня 2019

1-й вопрос: так что теперь, когда я вызываю метод Calculate (), он предпочитает вызывать метод, который принимает аргумент базового класса. Какова цель этого?

Ответ: Как может быть иначе? Компилятор не сможет определить «фактический» тип объекта, потому что он может быть действительно известен только во время выполнения. Вы несете ответственность за использование «отражения» (такого как GetType () и typeof ()) для приведения этого родительского объекта (фигуры) в его дочерний элемент (треугольник) и передачи его в качестве аргумента. Если бы это работало любым другим способом, вы не могли бы правильно реализовать метод ниже.

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

2-й вопрос: Есть ли у них какие-либо другие отличия от использования ссылки на базовый класс и создания экземпляра объекта из производного вместо использования производной ссылки?

Ответ: В памяти нет, ссылка всегда указывает на одни и те же данные, но Context изменится. Это означает, что к какому типу объекта (дочернему или родительскому) относится объект, какие поля / методы могут быть доступны. К какому типу приведен объект, не влияет на то, что на самом деле хранится в куче, скорее это меняет то, к чему вы можете получить доступ. Это продемонстрировано из приведенного ниже фрагмента кода.

    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
    }
0 голосов
/ 24 июня 2019

Правильный способ реализации полиморфизма - это поместить вашу функцию вычисления в каждый из ваших классов (включая ваш базовый класс) без статичности.Затем вы вызываете функцию из экземпляров и получаете ожидаемый результат:

Shape shape = new Triangle(tc, 4, 4, 4);
shape.calculate(); <<-- this will output "triangle"
...