... how can I restrict an implementation of A to use a certain implementation of B in the method signature?
Use Case
Here is a Unit
interface and two enums that implement it:
public interface Unit { ... }
public enum ForceUnit implements Unit { ... }
public enum MassUnit implements Unit { ... }
Which is used by the Property
interface:
public interface Property {
public void setUnit( Unit unit ); // for example
}
public class Force implements Property { ... }
public class Mass implements Property { ... }
Here I want to be able to enforce that:
Force
uses only ForceUnit
in the setUnit
signatureMass
uses only MassUnit
in the setUnit
signatureWhen I try to do this, Eclipse complains:
The type
Mass
must implement the inherited abstract methodProperty.setUnit(unit)
And promptly suggests two quick fixes:
Mass mass = new Mass();
@Override
annotation. I don't know if this is the right fix, but to me this smacks of clumsiness.Definition of a Java Method Signature It's the combination of the method name and the parameter list. The reason for the emphasis on just the method name and parameter list is because of overloading. It's the ability to write methods that have the same name but accept different parameters.
Like a class, an interface can have methods and variables, but the methods declared in an interface are by default abstract (only method signature, no body). Interfaces specify what a class must do and not how.
An interface is declared by using the interface keyword. It provides total abstraction; means all the methods in an interface are declared with the empty body, and all the fields are public, static and final by default. A class that implements an interface must implement all the methods declared in the interface.
8. What happens when a constructor is defined for an interface? Explanation: Constructor is not provided by interface as objects cannot be instantiated. 9.
You can use generics
public interface Property<U extends Unit> {
public void setUnit(U unit ); // for example
}
public class Force implements Property<ForceUnit> {
@Override
public void setUnit(ForceUnit unit) { }
}
public class Mass implements Property<MassUnit> {
@Override
public void setUnit(MassUnit unit) { }
}
Note: This does mean you can still do
Property raw = new Mass();
raw.setUnit(ForceUnit.NEWTON); // ClassCastException
however this will cause a class cast exception as the compiler is unable to check the raw type at run time.
What you should do is
Property<Mass> raw = new Mass();
raw.setUnit(ForceUnit.NEWTON); // doesn't compile.
Why does marking the class as abstract resolve the issue?
Making the classes abstract means that setUnit(Unit)
hasn't actually been implemented but for an abstract class this is ok.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With