3

In the code snippet above i have a base class Shape and two derived classes from it Rectangle and Triangle. I instantiate them but for the one Triangle object I use reference type of his base class.
So now when I call a method calculate() it will prefer to call the method that is taking the base class argument.

What is the purpose of this?

I am creating Triangle object not Shape object I just use the reference of the base class. And my other question is are they any other differences from using the reference of the base class and instantiating the object from the derived instead of using derived reference?

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");
}
  • Mind [edit]ing in the question the `Triangle`, `Rectangle`, `Shape` class definition? – xdtTransform Jun 24 '19 at 14:30
  • This is really confusing, partially because there are two questions. The first question seems to be why you're creating a `Triangle` and assigning it to a variable declared as `Shape`. That would make sense in any scenario where you needed to operate on a shape and you didn't care whether it was a rectangle, triangle, or any other shape. Perhaps you want to deal with methods or properties of the base class and you don't want that code to know or care about the difference between a rectangle, triangle, or something else. – Scott Hannen Jun 24 '19 at 14:35
  • @Scott Hannen Maybe i was not clear about my question. See the code snippet again please. –  Jun 24 '19 at 14:37
  • Actually, none of those static methods make sense (to me at least) because they each receive an argument of a different type but they don't do anything with those arguments. If those methods were calling some method or property on the arguments passed to them then we could talk about the difference in how they behave and why. But as it is, it makes no difference at all if you pass `Shape`, `Rectangle`, or `Triangle`. – Scott Hannen Jun 24 '19 at 14:40
  • @Scott Hannen It makes difference which method will be executed if you call Calculate with base ref type or with derived ref type ? –  Jun 24 '19 at 14:41
  • @xdtTransform Okay thank you. –  Jun 24 '19 at 14:43
  • 1
    Are you asking how it determines which `calculate` method to call? If that's the question, what you want to know about is *overloaded method resolution.* In other words, there are multiple methods with the same name but different signatures. How does it decide which one to call? I didn't search through the answers to find a really good one, but that's the thing to look for. – Scott Hannen Jun 24 '19 at 14:49
  • @Scott Hannen Exactly. Thank you, I will search. –  Jun 24 '19 at 14:50
  • Here is a good dupe https://stackoverflow.com/questions/5173339/how-does-the-method-overload-resolution-system-decide-which-method-to-call-when . for the first question. – xdtTransform Jun 24 '19 at 14:51
  • One other suggestion - I'd break this up into two questions, although that's harder now because there are answers that address both questions. So if you delete part of the question, some of the answers won't make sense anymore. But it's way better to keep them separate. – Scott Hannen Jun 24 '19 at 14:52
  • 2
    Just a suggestion, I think the title should be changed to "overloaded" methods instead of "overridden" methods. – Cabbage Champion Jun 24 '19 at 15:17

2 Answers2

5

1ST Question: So now when I call a method calculate() it will prefer to call the method that is taking the base class argument. What is the purpose of this?

Answer: How could it be any other way? The compiler would have no way to determine the "actual" type of the object because that can only be truly known at run time. It would be your responsibility to use "reflection" (Such as GetType() and typeof() ) to cast that parent object (shape) into its child (triangle) and then pass that as a argument. If it worked any other way, you could not properly implement the method below.

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

2nd Question: Is are they any other differences from using the reference of the base class and instantiating the object from the derived instead of using derived reference?

Answer: In memory no, the reference is always pointing to the same data but the Context will change. This means that which type of object(child or parent) the object is determines which fields/methods can be accessed. Which type the object is cast to does not alter what is actually stored on the heap, rather it changes what you can access. This is demonstrated from the below snippet of code.

    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
    }
Cabbage Champion
  • 1,193
  • 1
  • 6
  • 21
0

The right way to implement polymorphism is to place your calculate function in each of your classes (including your base class) without it being static. Then you would call the function from the instances and you would get your expected result:

Shape shape = new Triangle(tc, 4, 4, 4);
shape.calculate(); <<-- this will output "triangle"
Elias N
  • 1,430
  • 11
  • 19
  • I know that. Ok from the feedback's i understand maybe what i try to understand is not relevant or maybe i don't ask it right : ) Thank you anyway. –  Jun 24 '19 at 14:45