简体   繁体   中英

Use of abstract classes, interface and List in C#

I have the following code sections and I am trying to implement a method that returns a list. My structure is as follows : abstract class "Coordinates" -> public class "YCoordinate" with my interface pointing to "YCoordinate". I don't want my interface directly chatting to my abstract class as I feel the implementations of my abstract class is responsible for work.

Interface :

interface IYCoordinate
{
    System.Collections.Generic.List<Coordinates> GetYCoordinateList();
}

Abstract class :

public abstract class Coordinates
{
    private int coordinatePriority;
    private int coordinate;

    public Coordinates(int CoordinatePriority, int Coordinate)
    {
        this.CoordinatePriority = CoordinatePriority;
        this.Coordinate = Coordinate;
    }

    public Coordinates() { }
    public int CoordinatePriority { get { return coordinatePriority; } set { coordinatePriority = value; } }
    public int Coordinate { get { return coordinate; } set { coordinate = value; } }

    public virtual List<Coordinates> GetYCoordinateList()
    {
        throw new System.NotImplementedException();
    }
}

Implementation of Interface and abstract class (this is the part that breaks):

public class YCoordinate : Coordinates, IYCoordinate
{
    public override List<Coordinates> GetYCoordinateList() 
    {
        List<Coordinates> _list = new List<Coordinates>();
        _list.Add(new IYCoordinate(1, 5000));
        _list.Add(new IYCoordinate(2, 100000));
        return _list;
    }
}

However, I am trying to return a list of Coordinates and getting stuck on the public override function in the "YCoordinate" class as I cannot instantiate the Coordinates class directly (because its abstract). How can I return a list of Coordinates? The same error happens if I put in IYCoordinate as shown above.

Maybe my implementation is completely wrong? Any recommendation for doing it better would be welcome.

Later on there will be XCoordinate class and so on. If this approach seems like a bit much its because I am trying to get the hang of the theory behind this.

This is how I would do it:

1) you have one interface - IYCoordinate , but you are saying you will want to have IXCoordinate and IZCoordinate too. Just use single interface - ICoordinate and one function - GetCoordinateList :

interface ICoordinate
{
    IList<Coordinates> GetCoordinateList();
}

Actually, this intefrace can be eliminated if you are using my approach

2) in your abstract class you will have a stub for GetCoordinateList which does nothing

public abstract class Coordinates: ICoordinate
{
    public virtual List<Coordinates> GetCoordinateList()
    {
        throw new System.NotImplementedException();
    }
}

Actually you can eliminate ICoordinate interface altogether and use only abstract class. It's ffine.

3) You will derive one(or more than one) classes from that Coordinates class and implement GetCoordinate as you like

public class YCoordinate : Coordinates
{
    public override List<Coordinates> GetCoordinateList() 
    {
        List<Coordinates> _list = new List<Coordinates>();
        _list.Add(new YCoordinate(1, 5000));
        _list.Add(new YCoordinate(2, 100000));
        return _list;
    }
}

Thus you are having one single interface and one single function name to get coordinates from any class derived from Coordinates . If you will add XCoordinate class in future you will need to implement the same function with the same name. And when you will be instantiating XCoordinate or YCoordinate or WhateverCoordinate class you will always know there is a GetCoordinateList function that you need

var coordClass = new XCoordinate();
coordClass.GetCoordinateList();

Moreover, when passing something that has to have GetCoordinateList member you can use your interface ICoordinate or abstract class Coordinates wherever you like.

On these lines:

_list.Add(new IYCoordinate(1, 5000));
_list.Add(new IYCoordinate(2, 100000));

You need to instantiate an object of a class that derives from the Coordinates class. Here you are trying to create a new instance of an interface, and you cannot do that -- interface members have no definition!

Create a subclass of Coordinates and instantiate that instead. (Or remove the abstract keyword from the definition of this class -- it's not clear why it is abstract anyway, as there are no abstract members.)

You need at least one concrete class.

At the moment you only have abstract classes and interfaces.

the simple answer....change these two lines:

    _list.Add(new IYCoordinate(1, 5000));
    _list.Add(new IYCoordinate(2, 100000));

to this:

    _list.Add(new YCoordinate(1, 5000));
    _list.Add(new YCoordinate(2, 100000));

note that im creating the class there, not the interface.

Long answer...Blablablaster got that one right :-)

  • Starting from Blablablaster answer - In my opinion, you don't need an interface here.

    public abstract class Coordinates { public int CoordinatePriority { get; set; } public int Coordinate { get; set; }

     protected Coordinates(int CoordinatePriority, int Coordinate) { this.CoordinatePriority = CoordinatePriority; this.Coordinate = Coordinate; } public abstract List<Coordinates> GetCoordinateList(); 

    }

As you've noticed I've created an abstract method instead of the method in the interface. Every derived class must implement this method.

class YCoordinate:Coordinates
{
    public YCoordinate(int CoordinatePriority, int Coordinate) : 
        base(CoordinatePriority, Coordinate) //Call constructor of baseclass
    {
    }

    public override List<Coordinates> GetCoordinateList()
    {
        List<Coordinates> list = new List<Coordinates>();
        list.Add(new YCoordinate(1, 5000));
        list.Add(new YCoordinate(2, 100000));
        return list;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM