none
Inheriting Struct RRS feed

  • Question

  • Recently I had an interview but failed the coding test.

    The consumer code was given and the struct and interface was assignment.

    Here is the description of the assignment and consumer code. 

    Create a console application that can calculate the Euclidean distance between two points.  
    The points can be passed in as either 2 dimensional points or 3 dimensional points.  
    You should have an interface that exposes the necessary methods to clients.  
    Use object oriented principles appropriately to solve this problem,  
    the key here is how you design your application, not if you can calculate the Euclidean distance correctly.

    And the consumer code is like the following

    static void Main(string[] args)
    {
        // The definition for the types Point, Point2d and Point3d should be part of your design 
        Point point2d_1 = new Point2d(0, 0);
        Point point2d_2 = new Point2d(3, 4);
        Console.WriteLine("point2d_1 is " + point2d_1.Dist(point2d_2) + " distance away from point2d_2");
        Point point3d_1 = new Point3d(0, 0, 0);
        Point point3d_2 = new Point3d(3, 4, 5);
        Console.WriteLine("point2d_1 is " + point3d_1.Dist(point3d_2) + " distance away from point2d_2");
    }

    Struct can be inherited from an Interface but can't from other Struct.

    How to make Struct to do this?

    I want to know how to do this for the concrete knowledge.


    • Edited by Jeff0803 Monday, March 30, 2020 3:33 AM
    Monday, March 30, 2020 3:31 AM

Answers

  • I expect you would create an interface called "Point" that exposed a virtual "Dist" method.  Concrete structs Point2d and Point3d would both inherit from Point.  Each would have a constructor and and implementation of the Dist function.

    using System;
    
    public interface Point {
        int Dist( Point other );
    };
    
    public struct Point2d : Point
    {
        int x;
        int y;
    
        public Point2d( int _x, int _y )
        {
            x = _x;
            y = _y;
        }
    
        public int Dist( Point other )
        {
            Point2d xother = (Point2d)other;
            int dx = x - xother.x;
            int dy = y - xother.y;
            return (int)Math.Sqrt( dx * dx + dy * dy );
        }
    };
    
    public struct Point3d : Point
    {
        int x;
        int y;
        int z;
    
        public Point3d( int _x, int _y, int _z )
        {
            x = _x;
            y = _y;
            z = _z;
        }
    
        public int Dist( Point other )
        {
            Point3d xother = (Point3d)other;
            int dx = x - xother.x;
            int dy = y - xother.y;
            int dz = z - xother.z;
            return (int)Math.Sqrt( dx * dx + dy * dy + dz * dz );
        }
    };
    
    class Program
    {
        static void Main(string[] args)
        {
            // The definition for the types Point, Point2d and Point3d should be part of your design 
            Point point2d_1 = new Point2d(0, 0);
            Point point2d_2 = new Point2d(3, 4);
            Console.WriteLine("point2d_1 is " + point2d_1.Dist(point2d_2) + " distance away from point2d_2");
            Point point3d_1 = new Point3d(0, 0, 0);
            Point point3d_2 = new Point3d(3, 4, 5);
            Console.WriteLine("point2d_1 is " + point3d_1.Dist(point3d_2) + " distance away from point2d_2");
        }
    }
    


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    • Marked as answer by Jeff0803 Monday, March 30, 2020 6:19 AM
    Monday, March 30, 2020 4:57 AM
  • In my opinion, the correct answer is that Point2d and Point3d have different data, and the Dist methods have different signatures, so why the hell would you use a common interface for the two?

    But if you are forced to use an interface (possibly at gunpoint), you could make Point2d a wrapper for Point3d, taking advantage of the fact that Point2d's data is a subset of Point3d's. The only problem is that Point2d would appear to have a Z-dimension, which is a bit misleading, but would not matter for the simple example in the question.

    namespace Test
    {
       class Program
       {
          static void Main(string[] args)
          {
             // The definition for the types Point, Point2d and Point3d should be part of your design 
             Point point2d_1 = new Point2d(0, 0);
             Point point2d_2 = new Point2d(3, 4);
             Console.WriteLine("point2d_1 is " + point2d_1.Dist(point2d_2) + " distance away from point2d_2");
             Point point3d_1 = new Point3d(0, 0, 0);
             Point point3d_2 = new Point3d(3, 4, 5);
             Console.WriteLine("point2d_1 is " + point3d_1.Dist(point3d_2) + " distance away from point2d_2");
          }
    
          public interface Point
          {
             int X { get; }
             int Y { get; }
             int Z { get; }
    
             int Dist(Point p);
          }
    
          public struct Point3d : Point
          {
             public int X { get; set; }
             public int Y { get; set; }
             public int Z { get; set; }
    
             public Point3d(int x, int y, int z)
             {
                X = x;
                Y = y;
                Z = z;
             }
    
             public int Dist(Point p)
             {
                int dx = X - p.X;
                int dy = Y - p.Y;
                int dz = Z - p.Z;
                return (int)Math.Sqrt(dx * dx + dy * dy + dz * dz);
             }
          }
    
          public struct Point2d : Point
          {
             Point3d P3d;
    
             public int X{get{return P3d.X;} }
             public int Y { get { return P3d.Y; } }
             public int Z { get { return P3d.Z; } }
    
             public Point2d(int x, int y)
             {
                P3d = new Point3d(x, y, 0);
             }
    
             public int Dist(Point p)
             {
                return P3d.Dist(p);
             }
          }
       }
    
    }


    • Edited by Ante Meridian Monday, March 30, 2020 5:57 AM Point2d is a struct, not a class
    • Marked as answer by Jeff0803 Monday, March 30, 2020 6:19 AM
    Monday, March 30, 2020 5:49 AM
  • It is an extremely strong convention that the names of interfaces always start with 'I', so I think you can be forgiven for getting confused. It confused me too.

    And I still think it's a dumb question. I would never use an interface in that sort of case.

    And by the way, classes don't 'inherit' from interfaces, they 'implement' interfaces. Classes inherit from other classes.

    • Marked as answer by Jeff0803 Monday, March 30, 2020 6:10 PM
    Monday, March 30, 2020 9:01 AM
  • In my opinion, the correct answer is that Point2d and Point3d have different data,
    and the Dist methods have different signatures, so why the hell would you use
    > a common interface for the two?

    The Dist methods have the same signatures.  Did you look at it?  This is a perfect case for inheritance.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    • Marked as answer by Jeff0803 Thursday, April 2, 2020 5:15 PM
    Monday, March 30, 2020 7:50 PM
  • No they don't. The argument for one is a Point2d and for the other it's a Point3d. You can artificially make them the same signatures by making Point2d and Point3d implement the same interface, but then you have to cast to the right concrete class inside the method, which defeats the purpose.
    • Marked as answer by Jeff0803 Thursday, April 2, 2020 5:15 PM
    Monday, March 30, 2020 11:07 PM

All replies

  • We will need to create an interface and the strcuts will implement it something like:

    public interface IPoint<T>
    {
        int Dist(T point);
    }


    and for 2d and 3d point struct we can implement the interface like below:

    public struct Point2d : IPoint<Point2d>
    {
        public int Dist(Point2d point)
        {
            throw new NotImplementedException();
        }
    }

    The consumer side code will look like:

     IPoint<Point2d> point2d_1 = new Point2d(0, 0);
     IPoint<Point2d> point2d_2 = new Point2d(3, 4);
    
    var distance = point2d_1.Dist(point2d_2);
    
    


    [If a post helps to resolve your issue, please click the "Mark as Answer" of that post or click Answered"Vote as helpful" button of that post. By marking a post as Answered or Helpful, you help others find the answer faster. ]


    Blog | LinkedIn | Stack Overflow | Facebook
    profile for Ehsan Sajjad on Stack Exchange, a network of free, community-driven Q&A sites




    Monday, March 30, 2020 4:51 AM
  • I expect you would create an interface called "Point" that exposed a virtual "Dist" method.  Concrete structs Point2d and Point3d would both inherit from Point.  Each would have a constructor and and implementation of the Dist function.

    using System;
    
    public interface Point {
        int Dist( Point other );
    };
    
    public struct Point2d : Point
    {
        int x;
        int y;
    
        public Point2d( int _x, int _y )
        {
            x = _x;
            y = _y;
        }
    
        public int Dist( Point other )
        {
            Point2d xother = (Point2d)other;
            int dx = x - xother.x;
            int dy = y - xother.y;
            return (int)Math.Sqrt( dx * dx + dy * dy );
        }
    };
    
    public struct Point3d : Point
    {
        int x;
        int y;
        int z;
    
        public Point3d( int _x, int _y, int _z )
        {
            x = _x;
            y = _y;
            z = _z;
        }
    
        public int Dist( Point other )
        {
            Point3d xother = (Point3d)other;
            int dx = x - xother.x;
            int dy = y - xother.y;
            int dz = z - xother.z;
            return (int)Math.Sqrt( dx * dx + dy * dy + dz * dz );
        }
    };
    
    class Program
    {
        static void Main(string[] args)
        {
            // The definition for the types Point, Point2d and Point3d should be part of your design 
            Point point2d_1 = new Point2d(0, 0);
            Point point2d_2 = new Point2d(3, 4);
            Console.WriteLine("point2d_1 is " + point2d_1.Dist(point2d_2) + " distance away from point2d_2");
            Point point3d_1 = new Point3d(0, 0, 0);
            Point point3d_2 = new Point3d(3, 4, 5);
            Console.WriteLine("point2d_1 is " + point3d_1.Dist(point3d_2) + " distance away from point2d_2");
        }
    }
    


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by Jeff0803 Monday, March 30, 2020 6:19 AM
    Monday, March 30, 2020 4:57 AM
  • In my opinion, the correct answer is that Point2d and Point3d have different data, and the Dist methods have different signatures, so why the hell would you use a common interface for the two?

    But if you are forced to use an interface (possibly at gunpoint), you could make Point2d a wrapper for Point3d, taking advantage of the fact that Point2d's data is a subset of Point3d's. The only problem is that Point2d would appear to have a Z-dimension, which is a bit misleading, but would not matter for the simple example in the question.

    namespace Test
    {
       class Program
       {
          static void Main(string[] args)
          {
             // The definition for the types Point, Point2d and Point3d should be part of your design 
             Point point2d_1 = new Point2d(0, 0);
             Point point2d_2 = new Point2d(3, 4);
             Console.WriteLine("point2d_1 is " + point2d_1.Dist(point2d_2) + " distance away from point2d_2");
             Point point3d_1 = new Point3d(0, 0, 0);
             Point point3d_2 = new Point3d(3, 4, 5);
             Console.WriteLine("point2d_1 is " + point3d_1.Dist(point3d_2) + " distance away from point2d_2");
          }
    
          public interface Point
          {
             int X { get; }
             int Y { get; }
             int Z { get; }
    
             int Dist(Point p);
          }
    
          public struct Point3d : Point
          {
             public int X { get; set; }
             public int Y { get; set; }
             public int Z { get; set; }
    
             public Point3d(int x, int y, int z)
             {
                X = x;
                Y = y;
                Z = z;
             }
    
             public int Dist(Point p)
             {
                int dx = X - p.X;
                int dy = Y - p.Y;
                int dz = Z - p.Z;
                return (int)Math.Sqrt(dx * dx + dy * dy + dz * dz);
             }
          }
    
          public struct Point2d : Point
          {
             Point3d P3d;
    
             public int X{get{return P3d.X;} }
             public int Y { get { return P3d.Y; } }
             public int Z { get { return P3d.Z; } }
    
             public Point2d(int x, int y)
             {
                P3d = new Point3d(x, y, 0);
             }
    
             public int Dist(Point p)
             {
                return P3d.Dist(p);
             }
          }
       }
    
    }


    • Edited by Ante Meridian Monday, March 30, 2020 5:57 AM Point2d is a struct, not a class
    • Marked as answer by Jeff0803 Monday, March 30, 2020 6:19 AM
    Monday, March 30, 2020 5:49 AM
  • The interviewer's instruction was not to change consumer code.

    We have to leave consumer code as is but create struct and interface.

    Monday, March 30, 2020 6:15 AM
  • In my opinion, the correct answer is that Point2d and Point3d have different data, and the Dist methods have different signatures, so why the hell would you use a common interface for the two?

    It was just a coding test from my interview.

    They wanted to see how to use interface. 

    Monday, March 30, 2020 6:23 AM
  • I failed the test because I tried to create struct and interface like following.

    Interface IPoint
    {
    ...
    }
    Struct Point : IPoint
    {
    ...
    }
    Struct Point2d : Point
    {
    ...
    }
    Struct Point3d : Point
    {
    ...
    }

    I forgot Struct can't inherit from other Struct.

    I should have declared Point as an Interface and Point2d, Point3d should inherit from Point interface as your code. That was my mistake.

    Thanks

    Monday, March 30, 2020 6:27 AM
  • It is an extremely strong convention that the names of interfaces always start with 'I', so I think you can be forgiven for getting confused. It confused me too.

    And I still think it's a dumb question. I would never use an interface in that sort of case.

    And by the way, classes don't 'inherit' from interfaces, they 'implement' interfaces. Classes inherit from other classes.

    • Marked as answer by Jeff0803 Monday, March 30, 2020 6:10 PM
    Monday, March 30, 2020 9:01 AM
  • In my opinion, the correct answer is that Point2d and Point3d have different data,
    and the Dist methods have different signatures, so why the hell would you use
    > a common interface for the two?

    The Dist methods have the same signatures.  Did you look at it?  This is a perfect case for inheritance.


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by Jeff0803 Thursday, April 2, 2020 5:15 PM
    Monday, March 30, 2020 7:50 PM
  • No they don't. The argument for one is a Point2d and for the other it's a Point3d. You can artificially make them the same signatures by making Point2d and Point3d implement the same interface, but then you have to cast to the right concrete class inside the method, which defeats the purpose.
    • Marked as answer by Jeff0803 Thursday, April 2, 2020 5:15 PM
    Monday, March 30, 2020 11:07 PM