Let's say I have following interface:
interface Mammal {
void marry(Mammal m);
Mammal giveBirthTo();
}
However, this doesn't say quite exactly what I want.
Obviously, a human can't marry a dog, nor give birth to a cat. So how can I embed this information into the interface, such that the input type and output type can be changed automatically as it gets implemented?
You could use generics and change your design.
Something in the lines of:
interface Marriable<T extends Mammal> {
void marry(T sweetHalf);
T giveBirthTo();
}
... where Mammal is your top interface or abstract class, and Human, Dog, Unicorn etc. extend / implement it.
You can generify your interface using a recursive type variable:
interface Mammal<T extends Mammal<T>> {
void marry(T m);
T giveBirthTo();
}
This way, the Java compiler can give you a certain validation level. Notice however that this approach is still open to abuse. For example:
class Cat implements Mammal<Cat> {
#Override void marry(Cat cat) { ... }
#Override Cat giveBirthTo() { ... }
}
class Dog implements Mammal<Cat> { // implements wrong interface
#Override void marry(Cat cat) { ... }
#Override Cat giveBirthTo() { ... }
}
The compiler can only assure that you implement the Mammal interface by some sub type of the same interface, but not by the particular class that implements it. This latter type constraint cannot be expressed in the Java programming language.
Generics. Try with
private static interface Race {
}
private static class Human implements Race {}
private static class Canine implements Race {}
private static interface Being<R extends Race> {
void marry(Being<R> other);
Being<R> giveBirthTo();
}
private void tryMe() {
Being<Human> aHuman = new Being<Human>() {
#Override
public void marry(Being<Human> other) {
}
#Override
public Being<Human> giveBirthTo() {
return null;
}
};
Being<Canine> aCanine = new Being<Canine>() {
#Override
public void marry(Being<Canine> other) {
}
#Override
public Being<Canine> giveBirthTo() {
return null;
}
};
aHuman.marry(aCanine); // not possible
}
Related
Hey you people out there,
I'm asking myself the following question. This should be done in Java, but since I don't know how to do it anyway just a concept would help too:
I have the following code:
public abstract class A {
protected enum AType implements AInterface {
A_VALUE
}
public AInterface[] possibleRequests() {
AInterface types = AType.values();
return ArrayUtils.concat(types, possibleFurtherRequests());
}
public abstract AInterface[] possibleFurtherRequests();
}
public class B extends A {
protected enum BType implements BInterface {
B_VALUE
}
#Override
protected AInterface[] possibleFurtherRequests() {
//Here is my problem.
return BType.values();
}
}
public interface AInterface {
}
public interface BInterface extends AInterface {
}
What I want to do is have these possibleRequest-methods in indefinite depth. They should only be accessible via A, I do not and should not know which class the object of type A belongs to.
What I mean by indefinite depth is, that say this concept was extended with C extends B. I now want to access all values from A, B and C. How do I enforce, that whenever a new subclass is added the programmer is forced to define these AInterface-enumerations (optional) and how do I force him to implement a method that is then called recursively up the class Hierarchy (not optional).
I don't need help defining an abstract method, or overriding one. What I want to do is NOT override the existing one and NOT add an abstract method to each inheriting class that gets called.
I honestly don't know how to ask this question but I hope someone out there understands what I mean.
If not leave a comment.
Visibility of the methods is important. You can't force the subclasses to implement the now NOT abstract possibleFurtherRequests, but that is the only method they need. You also can't force them to call the super method either. Code reviews work nicely for that.
protected enum AType implements AInterface {
A_VALUE
}
protected enum BType implements BInterface {
B_VALUE
}
public abstract class A {
final public AInterface[] possibleRequests() {
return possibleFurtherRequests();
}
protected AInterface[] possibleFurtherRequests() {
return AType.values();
}
protected AInterface[] combine(AInterface[] some, AInterface[] more) {
AInterface[] combined = new AInterface[some.length + more.length];
System.arraycopy(some, 0, combined, 0, some.length);
System.arraycopy(more, 0, combined, some.length, more.length);
return combined;
}
}
public class B extends A {
#Override
protected AInterface[] possibleFurtherRequests() {
return combine(super.possibleFurtherRequests(), BType.values());
}
}
public interface AInterface {
}
public interface BInterface extends AInterface {
}
public void test() {
AInterface[] result = new B().possibleRequests();
Stream.of(result).forEach(System.out::println);
}
And the result is
A_VALUE
B_VALUE
Assume we have a class Animal, with subclasses as cat, eagle
Now I have a method:
public void process(Animal animal) {
if (animal instanceof Cat) {
if (!animal.meow()) {
throw exception("cat does not meow");
} else {
animal.feedFish();
}
}
if (animal instanceof eagle) {
if (!animal.fly()) {
throw exception("eagle does not fly");
} else {
animal.checkMaxFlightAltitude();
}
}
}
Here cat has 2 methods meow and feedfish which are completely different than eagle's methods fly and checkmaxflight
Most design patterns revolve around assumptions that subclasses have a common method like Shape draw() inherited by circle draw and square draw
Is there some way to do validations on subclasses, such as cat and eagle without instanceof check ?
Any good design pattern ( assuming subclasses dont share a method in base class ? )
You could have an abstract process method in Animal and implement it in the subclasses:
class Animal {
protected abstract void process();
public static void process(Animal a) { a.process(); }
}
class Cat {
void process() {
if (!meow()) throw exception("cat does not meow");
else feedFish();
}
public boolean meow() { ... }
public void feedFish() { ... }
}
You could use double dispatch by employing a visitor.
Example:
public class Animal {
public abstract void accept(AnimalVisitor v);
public boolean meow() {return false;}
public boolean fly() {return false;}
public void feedFish() {};
public void checkMaxFlightAltitude() {};
}
public class Cat extends Animal {
public void accept(AnimalVisitor v) {
v.visitCat(this);
}
public boolean meow() {return true;}
}
public class Eagle extends Animal {
public void accept(AnimalVisitor v) {
v.visitEagle(this);
}
public boolean fly() {return true;}
}
public interface AnimalVisitor {
void visitEagle(Eagle eagle);
void visitCat(Cat cat);
}
public class AnimalVisitorExample implements AnimalVisitor {
public void visitEagle(Eagle eagle) {
eagle.checkMaxFlightAltitude();
}
public void visitCat(Cat cat) {
cat.feedFish();
}
}
Animal animal = new Cat();
animal.accept(new AnimalVisitorExample());
(1) Is there some way to do validations on subclasses, such as cat and eagle without instanceof check ?
yes, there is. You could define a "validate" method (abstract in "Animal" class) and implement it in the specific subclasses. Depending on the validation result (e.g. exception / problem list) you can have the validate method throw some kind of "InvalidContentException" or provide the method call with an "ErrorHandler" that is informed about the bad things of an instance.
(2) assuming that the subclasses don't share a method in the base class: well, that one is a bit counter intuitive. On one hand you want to be able to do something on an "Animal", yet you don't want to define that capability on it?
You could define a Validator class that has separate validation methods (on for each kind of "Animal" subclass). That would eliminate the instanceof checks, however you would never be able to pass this Validator class other "Animals" (such as "Dog"), only "Cat" and "Eagle" (or subclasses thereof). You might also want to consider what you want to happen when passing subclasses of "Cat": are all sublasses of Cat validated in the same way or is there subclass specific behavior (like color, size, ...) for the different cat classes?
--> I think you should ask yourself if you want to be able to validate animals in general. Without having insight into your problem domain (which might have reasons not to do it), I'd recommend to have a "validate" method on the animal. You could also go for a visitor pattern, but that requires the Animal to have a "accept(AnimalVisitor visitor)" method and is slightly more code to write (presumably more than you want to)
This is when polymorphism comes in handy.
abstract class Animal {
abstract public void process(Animal animal);
}
class Cat extends Animal {
#Override
public void process(Animal animal) {
if (!this.meow()) {
throw exception("cat does not meow");
} else {
this.feedFish();
}
}
}
class Eagle extends Animal {
#Override
public void process(Animal animal) {
if (!this.fly()) {
throw exception("eagle does not fly");
} else {
this.checkMaxFlightAltitude();
}
}
}
I am way over thinking this: What I am trying to do is [hopefully not reinvent the wheel and] come up w/ a [Android] Java eventing mechanism that allows subclasses to pre-define an arbitrary set of "features" with getters and setters that fire individual callbacks.
I think I am fusioning some combination of Command, Visitor, Decorator, Facade and Observer patterns here, and confusing myself along the way.
I have been programming for well over 20 years, but I feel like a n00b on this fairly simple problem! :(
I have searched SO for the compiler error and read many of the results, but I still haven't found a solution that works for me.
(How to make a Java class that implements one interface with two generic types? seems to be the most relevant one that I have found, but I also want to generically get the values and fire events to callbacks when they are set).
First, let the below mostly valid code speak for itself...
interface IFeature
{
}
interface IFeatureCallbacks<T extends IFeature>
{
boolean onChanged(Feature<T> c);
}
public static class Feature<T extends IFeature>
{
private Set<IFeatureCallbacks<T>> listeners = new LinkedHashSet<>();
public void addListener(IFeatureCallbacks<T> listener)
{
listeners.add(listener);
}
public void removeListener(IFeatureCallbacks<T> listener)
{
listeners.remove(listener);
}
protected void onChanged()
{
for (IFeatureCallbacks<T> listener : listeners)
{
listener.onChanged(this);
}
}
}
//
interface IFeatureA
extends IFeature
{
int getA();
}
interface IFeatureACallbacks
extends IFeatureCallbacks<IFeatureA>
{
}
public static class FeatureA
extends Feature<IFeatureA>
implements IFeatureA
{
private int a;
public void setA(int value)
{
a = value;
onChanged();
}
#Override
public int getA()
{
return a;
}
}
//
interface IFeatureB
extends IFeature
{
boolean getB();
}
interface IFeatureBCallbacks
extends IFeatureCallbacks<IFeatureB>
{
}
public static class FeatureB
extends Feature<IFeatureB>
implements IFeatureB
{
private boolean b;
public void setB(boolean value)
{
b = value;
onChanged();
}
#Override
public boolean getB()
{
return b;
}
}
//
interface IDeviceWithFeatureA
extends IFeatureA
{
}
interface IDeviceWithFeatureACallbacks
extends IFeatureACallbacks
{
}
public static class DeviceWithFeatureA
extends Feature<IDeviceWithFeatureA>
implements IDeviceWithFeatureA
{
FeatureA a = new FeatureA();
public void addListener(IDeviceWithFeatureACallbacks listener)
{
a.addListener(listener);
}
public void setA(int value)
{
a.setA(value);
}
#Override
public int getA()
{
return a.getA();
}
}
//
interface IDeviceWithFeatureB
extends IFeatureB
{
}
interface IDeviceWithFeatureBCallbacks
extends IFeatureBCallbacks
{
}
public static class DeviceWithFeatureAB
extends Feature<IDeviceWithFeatureB>
implements IDeviceWithFeatureB
{
FeatureB b = new FeatureB();
public void addListener(IDeviceWithFeatureBCallbacks listener)
{
b.addListener(listener);
}
public void setB(boolean value)
{
b.setB(value);
}
#Override
public boolean getB()
{
return b.getB();
}
}
The above code seems to work fine, albeit something about it smells a bit off.
The problem is when I try to do this:
interface IDeviceWithFeatureAAndFeatureB
extends IFeatureA, IFeatureB
{
}
/*
Compiler error:
'IFeatureCallbacks' cannot be inherited with different type arguments 'IFeatureA' and 'IFeatureB'
*/
interface IDeviceWithFeatureAAndFeatureBCallbacks
extends IFeatureACallbacks, IFeatureBCallbacks
{
}
public static class DeviceWithFeatureAB
extends Feature<IDeviceWithFeatureAAndFeatureB>
implements IDeviceWithFeatureAAndFeatureB
{
FeatureA a = new FeatureA();
FeatureB b = new FeatureB();
public void addListener(IDeviceWithFeatureAAndFeatureBCallbacks listener)
{
a.addListener(listener);
b.addListener(listener);
}
public void setA(int value)
{
a.setA(value);
}
#Override
public int getA()
{
return a.getA();
}
public void setB(boolean value)
{
b.setB(value);
}
#Override
public boolean getB()
{
return b.getB();
}
}
I am less interested in trying to figure out how to make what I am trying to do compilable, and I am more interested in what about my abuse of a pattern is way off base so that I can re-write it to be both simpler and compile.
You are abusing the basic "pattern" of OOP -- inheritance. The adage is that "favor composition over inheritance". Think in terms of "contains", instead of "is-a".
Take Zoo for example. A zoo is just a bunch of animals, right? So naturally, we may want to declare Zoo as subtype of Set<Animal>. Perhaps even have class Zoo extends HashSet<Animal>.
However, that is likely a wrong design. A zoo is actually a lot of things. It contains a set of animals, sure; but it also contains a set of people (as workers, not exhibits (although...) ). So it's better to
class Zoo
Set<Animal> animals(){ ... }
Set<Person> workers(){ ... }
Anywhere we need to treat a zoo as a set of animals, just use zoo.animals(); think of it as a type cast, or projection. We don't need inheritance here.
In your design, you have too many types; what's worse, too many type relationships. It seems that you simply need one generic class that reads/writes value of T, and contains listeners of T
class Feature<T>
T value;
// getter
// setter
Set<ChangeListener<T>> listeners;
interface ChangeListener<T>
void onChange(T oldValue, T newValue)
A device contains a bunch of features
class SomeDevice
Feature<Integer> featureA = new Feature<>();
Feature<Boolean> featureB = new Feature<>();
That's it. You can operate on feature A of the device by operating on itsfeatureA.
In a project, I have a service and a class using that service. In this example case a repair service that will be used by vehicles. A repair service can only repair a certain type of vehicle: The garage can only repair cars. I need a method in the vehicle to repair it with an applicable service, repairUsingService(..).
My goal is to have a clean Vehicle base class and clean RepairService implementations. I have tried two ways of designing the repair method of the repair service:
repair(Vehicle<T> vehicle): This is ugly because implementations would need to do repair(Vehicle<Car> car) but it is obvious that a car is a vehicle.
repairSimple(T vehicle): Is nice with that but cannot be called from the Vehicle class without an ugly cast.
Is there a way to avoid casting but still only use the generic parameter type T (like in repairSimple(T))?
public class Vehicle<T extends Vehicle<T>> {
public void repairUsingService(RepairService<T> obj) {
obj.repair(this);
obj.repairSimple((T) this);
}
}
public class Car extends Vehicle<Car> {
}
public interface RepairService<T extends Vehicle<T>> {
void repair(Vehicle<T> vehicle);
void repairSimple(T vehicle);
}
public class Garage implements RepairService<Car> {
#Override
public void repair(Vehicle<Car> car) {
System.out.println("Car repaired.");
}
#Override
public void repairSimple(Car car) {
System.out.println("Car repaired.");
}
}
Could you use this implementation? This way both the vehicle knows, what repair service can repair it, and the service knows, what vehicles it can repair.
public interface RepairService<T extends Vehicle<?>> {
public void repair(T vehicle);
}
public interface Vehicle<T extends RepairService<?>> {
public void repairUsingService(T service);
}
public class Car implements Vehicle<Garage> {
#Override
public void repairUsingService(Garage service) {
}
}
public class Garage implements RepairService<Car>{
#Override
public void repair(Car vehicle) {
}
}
public class AuthorizedGarage extends Garage {
}
public class Train implements Vehicle<TrainDepot> {
#Override
public void repairUsingService(TrainDepot service) {
}
}
public class TrainDepot implements RepairService<Train> {
#Override
public void repair(Train vehicle) {
}
}
public class Test {
public static void main(String[] args) {
// this works:
new Car().repairUsingService(new Garage());
new Train().repairUsingService(new TrainDepot());
// and this works
new Garage().repair(new Car());
new TrainDepot().repair(new Train());
// but this does not (which is ok)
//new Garage().repair(new Train());
//new Car().repairUsingService(new TrainDepot());
// this also works
List<Car> cars = new ArrayList<>();
cars.add(new Car());
cars.get(0).repairUsingService(new Garage());
// this also works, if you have an expensive car ;)
new Car().repairUsingService(new AuthorizedGarage());
}
}
You could even have a base class for all your repair services to avoid code repetition:
public abstract class BaseRepairService<T extends Vehicle<?>> implements
RepairService<T> {
#Override
public void repair(T vehicle) {
}
}
Then your Garage would extend a BaseRepairService with a Car type parameter.
One way is to ask the subclass for itself:
abstract class Vehicle<T extends Vehicle<T>> {
public void repairUsingService(RepairService<T> obj) {
obj.repair(this);
obj.repairSimple(getThis());
}
abstract T getThis();
}
class Car extends Vehicle<Car> {
#Override
Car getThis(){
return this;
}
}
Let me present two reasonable alternatives.
The first is a variation of Gafter's Gadget:
public abstract class Vehicle<V extends Vehicle<V>> {
private boolean validate() {
Class<?> cls = getClass();
for(Class<?> sup;
(sup = cls.getSuperclass()) != Vehicle.class;
cls = sup
);
Type sup = cls.getGenericSuperclass();
if(!(sup instanceof ParameterizedType))
return false;
Type arg = ((ParameterizedType)sup).getActualTypeArguments()[0];
if(!(arg instanceof Class<?>))
return false;
return ((Class<?>)arg).isInstance(this);
}
protected Vehicle() {
assert validate() : "somebody messed up";
}
}
Since Vehicle is always parameterized by a subclass, it's OK to use this idiom. During development you run with assertions on and the constructor will throw an error if somebody extends the class incorrectly.
Now the unchecked cast is always safe.
The second is that RepairService no longer carries a type parameter. Instead, you keep a listing of Class<? extends Vehicle> the RepairService can repair.
public interface RepairService {
boolean canRepair(Vehicle v);
// if v can't be repaired, perhaps repair
// throws an exception or returns boolean instead of void
void repair(Vehicle v);
}
public class ServiceStation implements RepairService {
private final List<Class<? extends Vehicle>> types;
public ServiceStation(Class<? extends Vehicle>... types) {
this.types = Arrays.asList(types);
}
#Override
public boolean canRepair(Vehicle v) {
for(Class<? extends Vehicle> c : types) {
if(c.isInstance(v))
return true;
}
return false;
}
#Override
public void repair(Vehicle v) {
if(!canRepair(v))
throw new IllegalArgumentException();
// impl
}
}
At least for the Vehicle/RepairStation analogy this is probably much more usable than trying to force generics in to the design. Vehicle probably doesn't need a type parameter either anymore.
Maybe your actual program is different but you should always consider whether straight program logic solves the problem before introducing a parametric design. Trying to force generics to work in a situation where they are a suboptimal solution gets very awkward.
I have the following system in Java:
public class Human {
public void drown(Animal animal) {
if (animal instanceOf Fish) {
return;
} else {
animal.die();
}
}
}
public abstract class LandAnimal extends Animal{...}
public class Tiger extends LandAnimal{...}
public abstract class Fish extends Animal {...}
public class Trout extends Fish {...}
I have thought of adding a method
public abstract boolean drownable() {...}
in class Animal but I don't have access to the code of Animal class.
As I know the use of instanceOf is considered bad OOP practice. How do I avoid the use of instanceOf in this case? Thanks.
The drown() method in Human should be (by the way, why do humans want to drown animals?):
public void drown(Animal animal) {
animal.drown();
}
And each Animal will know what to do, for example:
// in class Tiger
public void drown() {
die();
}
// in class Fish
public void drown() {
// do nothing, fish can't drown
}
You would declare Animal.drown() and override it in Fish, containing the appropriate 'kill code' :).
So you'd just need to call drown() on each animal and each instance will behave according to its type specific method implementation.
public class Human {
public void drown(Animal animal) {
animal.drown();
}
}
Methods can be overloaded based on their arguments. You can have two different methods:
public void drown(Fish f) {
return;
}
public void drown(LandAnimal a) {
a.drown();
}
However, it should be noted that this makes determining whether some animal will drown the responsibility of the Human class, which, as other answers show, is arguable.