4

I have the following situation, but I feel like I'm doing something wrong... enter image description here

I used a interface for Field according to this post. The Field interface inherits from the Style class and Field1, 2 and 3 inherit from the Field interface. I want to construct a Label object with a couple of different types of fields which each have their own styling. I'm not sure if I'm doing it the right way like this, especially because I get the following error when I try to compile: Type 'Style' in interface list is not an interface

My code:

public interface Field : Style
{
    int Xpos { get; set; }
    int Ypos { get; set; }
    int Zindex { get; set; }
}

What is the best way to solve this?

EDIT

I know inheriting a class from an interface is impossible, but what would be the best approach here?

Community
  • 1
  • 1
Markinson
  • 2,077
  • 4
  • 28
  • 56
  • Should a Field not have a Style - therefore be a property. You don't really want to extend a Style to a Field. But you cannot make an interface inherit a class. – Andez Sep 13 '16 at 14:11
  • 2
    Interfaces cannot inherit from a class, only from other interfaces. – juharr Sep 13 '16 at 14:11
  • @juharr I figured haha but still thanks! How would I improve this? – Markinson Sep 13 '16 at 14:12
  • *Make interface extend class...* that's not possible – Rahul Sep 13 '16 at 14:13
  • 2
    Instead you could have Field1-3 inherit from Style and implement the Field interface. On a side note consider renaming Field to IField as the naming convention for interfaces is to put a capital i at the beginning of the name. – juharr Sep 13 '16 at 14:13
  • @juharr You should make this an answer since it addresses the OPs question. – qwerty_so Sep 13 '16 at 22:14
  • Interestingly (again) all answers are code-related and no UML solutions. So: are you after a programmatic or an UMLic solution? – qwerty_so Sep 13 '16 at 22:16
  • @ThomasKilian Either a UMLish solution or a code solution that reflects the UML is welcome :-) after all I'm going to build my code from my UML. Which of the answers do you recommend? Thanks! – Markinson Sep 14 '16 at 06:43
  • @juharr Is this what you mean: https://i.gyazo.com/d09e6ada1ad40230c3c37118acec2561.png Would this still work with the composition relationship? – Markinson Sep 14 '16 at 07:40
  • Exactly that is what @juharr meant (and why I said he should make this an answer) – qwerty_so Sep 14 '16 at 10:58
  • @ThomasKilian I'm not sure if my suggestion is the best as I do now know how the OP plans to use the "Fields" that are in the `Label` class. Specifically if the OP needs access to `Style` members, or only those defined in `Field` or `IField`. – juharr Sep 14 '16 at 12:00

4 Answers4

2

Find/Create an interface that is utilized by Style and inherit that interface on the field interface.

Note, field interface should be named IField.

If Style is your own class

public interface IStyle
{
    /* Style properties */
}
public class Style : IStyle
{
    /* Style implementations */
}

public interface IField : IStyle
{
    int Xpos { get; set; }
    int Ypos { get; set; }
    int Zindex { get; set; }
}

public class Field : Style, IField
{
    public int Xpos { get; set; }
    public int Ypos { get; set; }
    public int Zindex { get; set; }
}
Paul Tsai
  • 893
  • 6
  • 16
  • All my classes are made by myself so I'm not referring to any existing classes ;-) – Markinson Sep 13 '16 at 14:26
  • I've updated the code with a sample of creating an interface for Style called IStyle. IStyle is then inherited by the interface IField. The Field class inherits from the Style class and implements the IField interface. – Paul Tsai Sep 13 '16 at 18:29
0

I think where you are struggling with is the purpose of interfaces. An interface defines for a class what public members and methods will exist in an implementing class. This allows you to create a variable of type (your interface name) and then assign it a value of any instantiated class which implements the interface.

as far as improving your design, your three properties (x,y,z) can be defined in your interface and your label class and implement your field interface. It wont have a list of fields but would rather implement it, forcing it to have properties x,y and z with the draw method. your style would then have a list of fields where anything that implements your field interface can be added to this list. You can then confidently iterate over this list and call draw and know that it is there, regardless of what draw actually does.

xtreampb
  • 528
  • 6
  • 19
0

As it's been said, an interface can't extend a class, so I'll try another pattern. I don't know if it's pretty standard but when it comes to similar scenarios I choose the "Interface+Base Class" pattern. You define:

  • An interface with the minimum fields/methods required
  • A base (optionally abstract) class with the common functionallity

That way when you want to add features you can choose between extend the base class or implement the interface from scratch.

In your case it depends on the direction of the possible extensions but an example structure may be:

  • IStyle interface
  • StyleBase abstract class implementing IStyle and with an abstract Draw method
  • IField interface extending IStyle
  • FieldBase abstract class implementing IField and with and abstract Draw method
  • Label class extending StyleBase and with a List
  • Field1, Field2, Field3 classes extending FieldBase

As I said, that's just an example, it depends on the potential extending points.

rualmar
  • 229
  • 2
  • 8
0

When Inheritance fails, or make more troubles than it solves, Composition is most likely the way to go.

As you're not really saying much about the Draw() method I will just assume that it's not relevant to the problem here.

I think a good way to solve your issue here is to compose both your Field interface and your Label class with the Style class.

What I am suggesting is something like that:

public interface IField {
    Style style {get;set}
    /* Your property */
}
public class Label {
    Style style {get;set}
    IField field {get;set}
    /* Your property */
}
C.DuK
  • 1
  • 1