1

I have a given interface called IAbc, which consists of a method with a parameter of interface IXyz. I am not sure whether I should create an attribute IXyz or an attribute XyzImpl in my implementation of IAbc.

public interface IXyz { }
public class XyzImpl implements IXyz {
   public void doSomething() { ... }
}

public interface IAbc {
   public void setXyz(IXyz val);
   public IXyz getXyz();
}

Implementation 1:

public class AbcImpl1 implements IAbc {
   private XyzImpl attr;
   public void setXyz(IXyz val) {
      attr = (XyzImpl) val;
   }
   public IXyz getXyz() {
      return (IXyz) attr;
   }
   public void abc() {
      attr.doSomething();
   }
}

Implementation 2:

public class AbcImpl2 implements IAbc {
   private IXyz attr;
   public void setXyz(IXyz val) {
      attr = val;
   }       
   public IXyz getXyz() {
      return attr;
   }
   public void abc() {
      ((XyzImpl)attr).doSomething();
   }
}

Basically I only want to use my implementation XyzImpl within my implementation AbcImpl.

In any case, if I access the method abc() of one of my implementations, the accessing method needs to cast as well.

public void method() {
   AbcImpl1 abc;
   XyzImpl xyz = (XyzImpl) var.getXyz();
   xyz.abc();
}

Which way of implementation makes more sense? Casting in all classes where my implementation will be used is also not very handy. Is there any way to use only my implementation classes and not the interfaces?

Thank you in advance for your feedback!

BR, bobbel

bobbel
  • 11
  • 1
  • 3
  • it doesn't look like you have the right `IXyz` interface design. It looks like either `IXyz` should have the `abc()` method, or you shouldn't be using the `IXyz` interface. You shouldn't _need_ to use any methods that aren't accessible from the type you've stored the field as. – Louis Wasserman Mar 18 '16 at 00:42

3 Answers3

1

Just stick to interface IXyz so when you need to switch to other IXyz implementation for example from XyzImpl to XyzImpl1, you can be sure that AbcImpl will work as intended.

public class AbcImpl implements IAbc {
   private IXyz attr;
   public void setXyz(IXyz val) {
      attr = val;
   }
   public IXyz getXyz() {
      return attr;
   }
   public void abc() {
      attr.doSomething();
   }
}

If you always need access abc() method from IAbc implementation then you need to include abc() method in IAbc interface as well

public interface IAbc {
   public void setXyz(IXyz val);
   public IXyz getXyz();
   public void abc();
}

then you just need to use interface not implementation in any method calls.

public void method() {
   IAbc abc1 = new AbcImpl();
   abc1.setXyz(XyzImpl);
   IXyz xyz = abc1.getXyz();

   //same as calling abc1.getXyz().doSomething();
   abc1.abc();
}
Zamrony P. Juhara
  • 5,222
  • 2
  • 24
  • 40
0

Both ways are bad: if your class requires the parameter to have .abc method, and XYZ interfaces does not have it, you should not advertise, that you accept parameters of type XYZ. That is the whole purpose of having the type system in the first place. If you don't subscribe to that notion, you are better off writing code in ruby or perl.

Bottom line: either add abc to XYZ, or use XYZImpl in your ABCImpl class.

Dima
  • 39,570
  • 6
  • 44
  • 70
0

Your interface IXyz has no methods in it, so you need to think about why you need this interface.Also if you need only an XYImpl why does IAbc get and set IXyz? Usually "programming to an interface over implementation" is recommended but with no methods in IXyz, you are not achieving that. See this question as to why it is recommended to use inteface over implementation : What does it mean to "program to an interface"? and http://www.artima.com/lejava/articles/designprinciples.html

Community
  • 1
  • 1
pinki_13
  • 1
  • 1