Factory class design issue in java - java

I have two classes
public class PrepaidPackage {
private String name;
private String serviceClassID;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceClassID() {
return serviceClassID;
}
public void setServiceClassID(String serviceClassID) {
this.serviceClassID = serviceClassID;
}
}
other class is
public class PostpaidPackage {
private String name;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I want to create a factory class which on base of package type create relevant class. But if you look at above clasess they dont have same type of methods and variables. So please guide how create interface or abstract class for above class?
Now factory will return class name Package. Would i able to call methods which are not present in other class.
Updates
Please suggest if i break my package into two classes like
public abstract class MyPackage {
public abstract PackageSpec getSpec();
public abstract PackagePrepaidDetails getDetail();
}
Now common attributes will be in PackageSpec and prepaid stuff in packageDetails.
Its kind of abstract factory pattern.
public class PrepaidPackage extends MyPackage{
PackageSpec spec;
public Spec getSpec() {
spec = new PackageSpec();
spec.setTranferable(true)
spec.setName("abc");
return spec;
}
public PackagePrepaidDetails getDetails() {
details = new PackagePrepaidDetails ();
details.setServiceClassID(123)
return details;
}
}
public class PostpaidPackage extends MyPackage{
PackageSpec spec;
public Spec getSpec() {
spec = new PackageSpec();
spec.setTranferable(true)
spec.setName("abc");
return spec;
}
}

I recomment you to have an interface if you don't have already. You do not neccessarily need it, but it is a good practice if they are so similar:
public interface Package {
public boolean isTranferable();
public void setTranferable(boolean isTranferable);
public String getName();
public void setName(String name);
}
Then in your calling code, you have a Package from your factory and:
Package p = myFactory.nextPackage(); // or something
if (p instanceof PrepaidPackage) {
PrepaidPackage prepaid = (PrefpaidPackage)p;
// and do the thing you want
} else if (p instanceof PostpaidPackage) {
PostpaidPackage postpaid = (PostpaidPackage)p;
// amd do the other things
}
Thing you are recommended to llok into is the instanceof operator and type casting.

A quick fix, not an ideal one is to have an interface that represents all the methods in the Prepaid class and leave them unimplemented in the Postpaid. That will solve the problem in the short term. I would suggest that you have a relook of the classes and the usages to avoid unimplemented methods in the code.

Well for an abstract super class you have to group everything common to both :
public abstract class MyPackage { // not sure you can call a class just "Package"
private String name;
private boolean isTranferable;
public boolean isTranferable() {
return isTranferable;
}
public void setTranferable(boolean isTranferable) {
this.isTranferable = isTranferable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
then both inherits from it (the first adds serviceClassID and the second nothing)
your factory function will return a MyPackage (or AbstractPackage, whatever), but to access the specific function you'll have to cast after an instanceof test.

Two possible design choices you can make:
Have the prepaid package extend
postpaid package and your factory
then returns objects of type
postpaid package, the code which
calls the factory is then
responsible for inspecting the type.
Have a package interface which
defines all of the methods and have
postpaid package define the methods
to throw an
UnsupportedOperationException (ala
the way collections defines some
operations as optional.) or return
some kind of sentinel value (i.e. null)
For either of the above you could add another method getType() which returns an enum of the various package types you wish to implement, and this could then be used in the code that accesses the factory objects to determine which methods are available.

Related

How do I define a field in a subclass by strictly following a given UML?

I'm trying to implement the UML diagram below using java:
I only got recently exposed to UMLs and according to my understanding, I cannot set a field inside SBank or PBank to define their rate of interest. It can also be seen that in the class Bank there is no implementation for defining the rate of interest like using a setter method. I am looking for advice on how to go about this, or is there something wrong with the given UML? Below are some sample code I used to try and implement the UML into code:
public class BankInfo {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Bank {
private BankInfo info;
private int rateOfInterest;
public Bank(BankInfo info) {
this.info = info;
}
public void displayInterestRate(){
}
public int getRateOfInterest(){
return rateOfInterest;
}
}
public class SBank extends Bank{
private int rateOfInterest = 8;
public SBank(BankInfo info) {
super(info);
}
#Override
public int getRateOfInterest() {
return rateOfInterest;
}
}
This UML:
Does not show any rateOfInterest field in any class. What it shows is Bank is abstract and has an int-returning abstract method: getRateOfInterest(). You can tell the class and method are abstract because their names are italicized.
public abstract class Bank {
// other members...
public abstract int getRateOfInterest();
}
The UML further shows you need to override getRateOfInterest() in both SBank and PBank, both of which extend Bank, and return that implementation's rate of interest. You will be returning the value directly rather than storing it in a field. For example, SBank would look like:
public class SBank extends Bank {
public SBank(BankInfo info) {
super(info);
}
#Override
public int getRateOfInterest() {
return 8;
}
}
I got the value of 8 from the UML diagram which states:
Interest Rate of SBank is 8 %.

How do I minimize the amount of code for a hierarchy

This is for learning. I have an interface that is implemented by 2 classes, and I am supposed to reduce the amount of code I use in order to keep things more clean and less messy. Currently, the code looks like this:
public abstract class VClass implements IntFace {
protected String name;
public VClass(String name) {
this.name = name;
}
public int value (SClass sc) {//comes from a diff class
return sc.lookup(name);
}
public String getName() {
return name;
}
#Override
public String toString() {
return getName();
}
}
public abstract class NClass extends VClass implements IntFace {
public Number(String name) {
super(name);
this.name = name;
}
public int value (SClass sc) {
return sc.lookup(name);
}
public String getName() {
return name;
}
#Override
public String toString() {
return getName();
}
}
public interface IntFace {
public int value (SClass sc);
public String toString (int num);
}
can this code be more condensed?
You can remove the following things from your code:
implements IntFace from NClass declaration. Since NClass extends VClass, it implements IntFace as well.
this.name = name; from NClass constructor. name is initialized in a superclass constructor
value and getName methods from NClass. These methods are implemented in a superclass.
public modifier from interface methods declaration. Methods in interfaces are public by default.
Now you can also make name field private since it's no longer used in a NClass.

POJO multiple-hierarchy Builder

I'm trying to achieve a hierarchy of builder with more than 3 levels.
Something like:
public abstract class ElementBuilder {
protected String name;
public ElementBuilder setName(String name) {
this.name = name;
return this;
}
}
public abstract class OperationBuilder extends ElementBuilder {
protected String attribute;
public OperationBuilder setName(String attribute) {
this.attribute = attribute;
return this;
}
}
public abstract class FilterBuilder extends OperationBuilder {
....
}
The problem is that when I call an operation of the super class it's returning a builder of the that class. I don't want to duplicate the setter method in each child, cause it maybe contain some logic.
I tried using generics but I could not achieve it in a clean way.

Builder Pattern and Inheritance

I have an object hierarchy that increases in complexity as the inheritance tree deepens. None of these are abstract, hence, all of their instances serve a, more or less sophisticated, purpose.
As the number of parameters is quite high, I would want to use the Builder Pattern to set properties rather than code several constructors. As I need to cater to all permutations, leaf classes in my inheritance tree would have telescoping constructors.
I have browsed for an answer here when I hit some problems during my design. First of, let me give you a simple, shallow example to illustrate the problem.
public class Rabbit
{
public String sex;
public String name;
public Rabbit(Builder builder)
{
sex = builder.sex;
name = builder.name;
}
public static class Builder
{
protected String sex;
protected String name;
public Builder() { }
public Builder sex(String sex)
{
this.sex = sex;
return this;
}
public Builder name(String name)
{
this.name = name;
return this;
}
public Rabbit build()
{
return new Rabbit(this);
}
}
}
public class Lop extends Rabbit
{
public float earLength;
public String furColour;
public Lop(LopBuilder builder)
{
super(builder);
this.earLength = builder.earLength;
this.furColour = builder.furColour;
}
public static class LopBuilder extends Rabbit.Builder
{
protected float earLength;
protected String furColour;
public LopBuilder() { }
public Builder earLength(float length)
{
this.earLength = length;
return this;
}
public Builder furColour(String colour)
{
this.furColour = colour;
return this;
}
public Lop build()
{
return new Lop(this);
}
}
}
Now that we have some code to go on, imaging I want to build a Lop:
Lop lop = new Lop.LopBuilder().furColour("Gray").name("Rabbit").earLength(4.6f);
This call will not compile as the last chained call cannot be resolved, Builder not defining the method earLength. So this way requires that all calls be chained in a specific order which is very impractical, especially with a deep hierarchy tree.
Now, during my search for an answer, I came across Subclassing a Java Builder class which suggests using the Curiously Recursive Generic Pattern. However, as my hierarchy does not contain an abstract class, this solution will not work for me. But the approach relies on abstraction and polymorphism to function which is why I don't believe I can adapt it to my needs.
An approach I have currently settled with is to override all methods of the superclass Builder in the hierarchy and simply do the following:
public ConcreteBuilder someOverridenMethod(Object someParameter)
{
super(someParameter);
return this;
}
With this approach I can assure I am being returned an instance I can issue chain calls on. While this is not as worse as the Telescoping Anti-pattern, it is a close second and I consider it a bit "hacky".
Is there another solution to my problem that I am not aware of? Preferably a solution consistent with the design pattern. Thank you!
This is certainly possible with the recursive bound, but the subtype builders need to also be generic, and you need a few interim abstract classes. It's a little bit cumbersome, but it's still easier than the non-generic version.
/**
* Extend this for Mammal subtype builders.
*/
abstract class GenericMammalBuilder<B extends GenericMammalBuilder<B>> {
String sex;
String name;
B sex(String sex) {
this.sex = sex;
return self();
}
B name(String name) {
this.name = name;
return self();
}
abstract Mammal build();
#SuppressWarnings("unchecked")
final B self() {
return (B) this;
}
}
/**
* Use this to actually build new Mammal instances.
*/
final class MammalBuilder extends GenericMammalBuilder<MammalBuilder> {
#Override
Mammal build() {
return new Mammal(this);
}
}
/**
* Extend this for Rabbit subtype builders, e.g. LopBuilder.
*/
abstract class GenericRabbitBuilder<B extends GenericRabbitBuilder<B>>
extends GenericMammalBuilder<B> {
Color furColor;
B furColor(Color furColor) {
this.furColor = furColor;
return self();
}
#Override
abstract Rabbit build();
}
/**
* Use this to actually build new Rabbit instances.
*/
final class RabbitBuilder extends GenericRabbitBuilder<RabbitBuilder> {
#Override
Rabbit build() {
return new Rabbit(this);
}
}
There's a way to avoid having the "concrete" leaf classes, where if we had this:
class MammalBuilder<B extends MammalBuilder<B>> {
...
}
class RabbitBuilder<B extends RabbitBuilder<B>>
extends MammalBuilder<B> {
...
}
Then you need to create new instances with a diamond, and use wildcards in the reference type:
static RabbitBuilder<?> builder() {
return new RabbitBuilder<>();
}
That works because the bound on the type variable ensures that all the methods of e.g. RabbitBuilder have a return type with RabbitBuilder, even when the type argument is just a wildcard.
I'm not much of a fan of that, though, because you need to use wildcards everywhere, and you can only create a new instance using the diamond or a raw type. I suppose you end up with a little awkwardness either way.
And by the way, about this:
#SuppressWarnings("unchecked")
final B self() {
return (B) this;
}
There's a way to avoid that unchecked cast, which is to make the method abstract:
abstract B self();
And then override it in the leaf subclass:
#Override
RabbitBuilder self() { return this; }
The issue with doing it that way is that although it's more type-safe, the subclass can return something other than this. Basically, either way, the subclass has the opportunity to do something wrong, so I don't really see much of a reason to prefer one of those approaches over the other.
Confronted with the same issue, I used the solution proposed by emcmanus at: https://community.oracle.com/blogs/emcmanus/2010/10/24/using-builder-pattern-subclasses
I'm just recopying his/her preferred solution here. Let say we have two classes, Shape and Rectangle. Rectangle inherits from Shape.
public class Shape {
private final double opacity;
public double getOpacity() {
return opacity;
}
protected static abstract class Init<T extends Init<T>> {
private double opacity;
protected abstract T self();
public T opacity(double opacity) {
this.opacity = opacity;
return self();
}
public Shape build() {
return new Shape(this);
}
}
public static class Builder extends Init<Builder> {
#Override
protected Builder self() {
return this;
}
}
protected Shape(Init<?> init) {
this.opacity = init.opacity;
}
}
There is the Init inner class, which is abstract, and the Builder inner class, that is an actual implementation. Will be useful when implementing the Rectangle:
public class Rectangle extends Shape {
private final double height;
public double getHeight() {
return height;
}
protected static abstract class Init<T extends Init<T>> extends Shape.Init<T> {
private double height;
public T height(double height) {
this.height = height;
return self();
}
public Rectangle build() {
return new Rectangle(this);
}
}
public static class Builder extends Init<Builder> {
#Override
protected Builder self() {
return this;
}
}
protected Rectangle(Init<?> init) {
super(init);
this.height = init.height;
}
}
To instantiate the Rectangle:
new Rectangle.Builder().opacity(1.0D).height(1.0D).build();
Again, an abstract Init class, inheriting from Shape.Init, and a Build that is the actual implementation. Each Builder class implement the self method, which is responsible to return a correctly cast version of itself.
Shape.Init <-- Shape.Builder
^
|
|
Rectangle.Init <-- Rectangle.Builder
If anyone still bumped into the same problem, I suggest the following solution, that conforms "Prefer composition over inheritance" design pattern.
Parent class
The main element of it is the interface that parent class Builder must implement:
public interface RabbitBuilder<T> {
public T sex(String sex);
public T name(String name);
}
Here is the changed parent class with the change:
public class Rabbit {
public String sex;
public String name;
public Rabbit(Builder builder) {
sex = builder.sex;
name = builder.name;
}
public static class Builder implements RabbitBuilder<Builder> {
protected String sex;
protected String name;
public Builder() {}
public Rabbit build() {
return new Rabbit(this);
}
#Override
public Builder sex(String sex) {
this.sex = sex;
return this;
}
#Override
public Builder name(String name) {
this.name = name;
return this;
}
}
}
The child class
The child class Builder must implement the same interface (with different generic type):
public static class LopBuilder implements RabbitBuilder<LopBuilder>
Inside the child class Builder the field referencing parentBuilder:
private Rabbit.Builder baseBuilder;
this ensures that parent Builder methods are called in the child, however, their implementation is different:
#Override
public LopBuilder sex(String sex) {
baseBuilder.sex(sex);
return this;
}
#Override
public LopBuilder name(String name) {
baseBuilder.name(name);
return this;
}
public Rabbit build() {
return new Lop(this);
}
The constructor of Builder:
public LopBuilder() {
baseBuilder = new Rabbit.Builder();
}
The constructor of builded child class:
public Lop(LopBuilder builder) {
super(builder.baseBuilder);
}
I have adopted the following guidelines when creating object hierarchies with builders:
Make the constructor of the class at least protected and use it as copy constructor, thus pass it an instance of the class itself.
Make the fields non-final private and use getters to access them.
Add package private setters for the builders, which is also nice for object serialization frameworks.
Make a generic builder for each class that will have a subclass builder. This builder will already contain the setter methods for the current class, but we create also a second non generic builder for the class that contains the constructor and build method.
The builders will not have any fields. Instead the generic builder that is on top of the hierarchy will contain a generic field for the concrete object to be build.
The Rabbit will look like this:
public class Rabbit {
// private non-final fields
private String sex;
private String name;
// copy constructor
Rabbit(Rabbit rabbit) {
sex = rabbit.sex;
name = rabbit.name;
}
// no-arg constructor for serialization and builder
Rabbit() {}
// getter methods
public final String getSex() {
return sex;
}
public final String getName() {
return name;
}
// package private setter methods, good for serialization frameworks
final void setSex(String sex) {
this.sex = sex;
}
final void setName(String name) {
this.name = name;
}
// create a generic builder for builders that have subclass builders
abstract static class RBuilder<R extends Rabbit, B extends RBuilder<R, B>> {
// the builder creates the rabbit
final R rabbit;
// here we pass the concrete subclass that will be constructed
RBuilder(R rabbit) {
this.rabbit = rabbit;
}
public final B sex(String sex) {
rabbit.setSex(sex);
return self();
}
public final B name(String name) {
rabbit.setName(name);
return self();
}
#SuppressWarnings("unchecked")
final B self() {
return (B) this;
}
}
// the builder that creates the rabbits
public static final class Builder extends RBuilder<Rabbit, Builder> {
// creates a new rabbit builder
public Builder() {
super(new Rabbit());
}
// we could provide a public copy constructor to support modifying rabbits
public Builder(Rabbit rabbit) {
super(new Rabbit(rabbit));
}
// create the final rabbit
public Rabbit build() {
// maybe make a validate method call before?
return new Rabbit(rabbit);
}
}
}
and our Lop:
public final class Lop extends Rabbit {
// private non-final fields
private float earLength;
private String furColour;
// copy constructor
private Lop(Lop lop) {
super(lop);
this.earLength = lop.earLength;
this.furColour = lop.furColour;
}
// no-arg constructor for serialization and builder
Lop() {}
// getter methods
public final float getEarLength() {
return earLength;
}
public final String getFurColour() {
return furColour;
}
// package private setter methods, good for serialization frameworks
final void setEarLength(float earLength) {
this.earLength = earLength;
}
final void setFurColour(String furColour) {
this.furColour = furColour;
}
// the builder that creates lops
public static final class Builder extends RBuilder<Lop, Builder> {
public Builder() {
super(new Lop());
}
// we could provide a public copy constructor to support modifying lops
public Builder(Lop lop) {
super(new Lop(lop));
}
public final Builder earLength(float length) {
rabbit.setEarLength(length);
return self(); // this works also here
}
public final Builder furColour(String colour) {
rabbit.setFurColour(colour);
return self();
}
public Lop build() {
return new Lop(rabbit);
}
}
}
Pros:
The builders will exactly mirror the object hierarchy of your classes with a single derivative for each generic builder to build the objects of the current class. No need to create artificial parents.
The class does not have a dependency to its builder. All it needs is an instance of itself to copy the fields, which might be useful for alternative factories.
The classes work very well with serialization frameworks like JSON or Hibernate, since they most often need getters and setters to be present. E.g. Jackson works fine with package private setters.
No need to duplicate fields in the builder. The builder contains the object to be constructed.
No need to override setter methods in the subtype builders since the direct parent class is generic.
Build-in support for copy constructors to allow creating a modified version of an instance, making the objects 'kind of immutable'.
Cons:
Requires at least one additional generic builder.
Fields are not final, thus it's not safe to make them public.
The class itself needs additional setter methods to be called from the builders.
Let's create some rabbits..
#Test
void test() {
// creating a rabbit
Rabbit rabbit = new Rabbit.Builder() //
.sex("M")
.name("Rogger")
.build();
assertEquals("M", rabbit.getSex());
// create a lop
Lop lop = new Lop.Builder() //
.furColour("Gray")
.name("Rabbit")
.earLength(4.6f)
.build();
// modify only the name of the lop
lop = new Lop.Builder(lop) //
.name("Lop")
.build();
assertEquals("Gray", lop.getFurColour());
assertEquals("Lop", lop.getName());
}
This form seems to nearly work. It is not very tidy but it looks like it avoids your issues:
class Rabbit<B extends Rabbit.Builder<B>> {
String name;
public Rabbit(Builder<B> builder) {
this.name = builder.colour;
}
public static class Builder<B extends Rabbit.Builder<B>> {
protected String colour;
public B colour(String colour) {
this.colour = colour;
return (B)this;
}
public Rabbit<B> build () {
return new Rabbit<>(this);
}
}
}
class Lop<B extends Lop.Builder<B>> extends Rabbit<B> {
float earLength;
public Lop(Builder<B> builder) {
super(builder);
this.earLength = builder.earLength;
}
public static class Builder<B extends Lop.Builder<B>> extends Rabbit.Builder<B> {
protected float earLength;
public B earLength(float earLength) {
this.earLength = earLength;
return (B)this;
}
#Override
public Lop<B> build () {
return new Lop<>(this);
}
}
}
public class Test {
public void test() {
Rabbit rabbit = new Rabbit.Builder<>().colour("White").build();
Lop lop1 = new Lop.Builder<>().earLength(1.4F).colour("Brown").build();
Lop lop2 = new Lop.Builder<>().colour("Brown").earLength(1.4F).build();
//Lop.Builder<Lop, Lop.Builder> builder = new Lop.Builder<>();
}
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
Although I have successfully built Rabbit and Lop (in both forms) I cannot at this stage work out how to actually instantiate one of the Builder objects with it's full type.
The essence of this method relies on the cast to (B) in the Builder methods. This allow you to define the type of object and the type of the Builder and retain that within the object while it is constructed.
If anyone could work out the correct syntax for this (which is wrong) I would appreciate it.
Lop.Builder<Lop.Builder> builder = new Lop.Builder<>();
I did some experimenting and I found this to work quite nicely for me.
Note that I prefer to create the actual instance at the start and the call all the setters on that instance. This is just a preference.
The main differences with the accepted answer is that
I pass a parameter that indicated the return type
There is no need for an Abstract... and a final builder.
I create a 'newBuilder' convenience method.
The code:
public class MySuper {
private int superProperty;
public MySuper() { }
public void setSuperProperty(int superProperty) {
this.superProperty = superProperty;
}
public static SuperBuilder<? extends MySuper, ? extends SuperBuilder> newBuilder() {
return new SuperBuilder<>(new MySuper());
}
public static class SuperBuilder<R extends MySuper, B extends SuperBuilder<R, B>> {
private final R mySuper;
public SuperBuilder(R mySuper) {
this.mySuper = mySuper;
}
public B withSuper(int value) {
mySuper.setSuperProperty(value);
return (B) this;
}
public R build() {
return mySuper;
}
}
}
and then a subclass look like this:
public class MySub extends MySuper {
int subProperty;
public MySub() {
}
public void setSubProperty(int subProperty) {
this.subProperty = subProperty;
}
public static SubBuilder<? extends MySub, ? extends SubBuilder> newBuilder() {
return new SubBuilder(new MySub());
}
public static class SubBuilder<R extends MySub, B extends SubBuilder<R, B>>
extends SuperBuilder<R, B> {
private final R mySub;
public SubBuilder(R mySub) {
super(mySub);
this.mySub = mySub;
}
public B withSub(int value) {
mySub.setSubProperty(value);
return (B) this;
}
}
}
and a subsub class
public class MySubSub extends MySub {
private int subSubProperty;
public MySubSub() {
}
public void setSubSubProperty(int subProperty) {
this.subSubProperty = subProperty;
}
public static SubSubBuilder<? extends MySubSub, ? extends SubSubBuilder> newBuilder() {
return new SubSubBuilder<>(new MySubSub());
}
public static class SubSubBuilder<R extends MySubSub, B extends SubSubBuilder<R, B>>
extends SubBuilder<R, B> {
private final R mySubSub;
public SubSubBuilder(R mySub) {
super(mySub);
this.mySubSub = mySub;
}
public B withSubSub(int value) {
mySubSub.setSubSubProperty(value);
return (B)this;
}
}
}
To verify it fully works I used this test:
MySubSub subSub = MySubSub
.newBuilder()
.withSuper (1)
.withSub (2)
.withSubSub(3)
.withSub (2)
.withSuper (1)
.withSubSub(3)
.withSuper (1)
.withSub (2)
.build();
The following IEEE conference contribution Refined Fluent Builder in Java gives a comprehensive solution to the problem.
It dissects the original question into two sub-problems of inheritance deficiency and quasi invariance and shows how a solution to these two sub-problems opens for inheritance support with code reuse in the classical builder pattern in Java.
As you cannot use generics, now probably the main task is to somehow loosen typing.
I don't know how you process those properties afterwards, but what if you used a HashMap for storing them as key-value pairs? So there will be just one set(key, value) wrapper method in the builder (or builder might not be necessary any more).
The downside would be additional type castings while processing the stored data.
If this case is too loose, then you could keep the existing properties, but have a general set method, which uses reflection and searches for setter method on the basis of 'key' name. Although I think reflection would be an overkill.

How can I add a protected method to a class implementing an interface in java?

I have a class called Property which has nothing but get-methods. All the fields will be set when a new instance of Propertyis created. Property implements an interface called IProperty.
Due to some bug in a library I use, I have to set the name of an instance of Property anew after its creation. Therefore it was suggested to create a WrapperPropertyclass that will provide a public setName-method which itself calls a therefore created setName()-method in Property, which will be protected/package view.
The problem is that I cannot make this method protected in Property, because Eclipse tells me to add it to the interface IProperty and make it public.
Is there some work-around to it?
WrapperIProperty:
public class WrapperIProperty {
private IProperty prop;
WrapperIProperty(Property prop) {
this.prop = prop;
}
public void setName(String name) {
prop.setName(name);
}
}
Property:
public class Property implements IProperty {
String name;
protected void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getFoobar() {
return 123;
}
public int getWhatever() {
return 987;
}
}
IProperty:
public interface IProperty {
public int getWhatever();
public int getFoobar();
public String getName();
}
This is how it looks at the moment. Obviously it won't work, since I cannot let the method be protected in the Property class. Therefore I best get rid of the interfacee entry somehow. But how?
What you probably want to do is to leave the IProperty interface alone (don't add the setName method to it) and create a delegating wrapper class which provides the method you want (wraps an implementation of the interface).
This way you can feed wrapped properties and regular properties to whatever needs them.
public class WrappedProperty implements IProperty {
private String name;
private Property prop;
WrappedProperty (Property prop) {
this.prop = prop;
}
protected void setName(String name) {
this.name = name;
}
public int getWhatever() {
return prop.getWhatever();
}
public int getFoobar() {
return prop.getFoobar();
}
public String getName() {
if (this.name == null) {
return prop.getName():
} else {
return this.name;
}
}
}
public class Property implements IProperty {
public String getName() {
return "blah";
}
public int getFoobar() {
return 123;
}
public int getWhatever() {
return 987;
}
}
public interface IProperty {
public int getWhatever();
public int getFoobar();
public String getName();
}
Methods in an Interface are public in scope so implementing class cannot override methods by reducing their accessibility. Make them public
You cannot have a public methodName in an Interface and a private or protected methodName in a Class implementing this Interface.
So you can have the methodName public in your Class :
this method do nothing
this method call [another]methodNameProtected (you give another name to a new protected method)
UPDATE
If you want it only in Interface you have to change your Interface in an AbstractClass and put in it the method
public final returnCode methodName if the method is common for all inherited classes
Found the solution to that problem:
WrapperIProperty :
public class WrapperIProperty {
private Property prop;
public WrapperIProperty(IProperty prop) {
this.prop = (Property) prop;
}
public void setName(String name) {
prop.setName(name);
}
}
Property:
public class Property implements IProperty {
private String name = null;
[...]
void setName(String name) {
this.name = name;
}
}
IProperty:
public interface IProperty {
[...]
}
This will do the job

Categories

Resources