Issue with generics and <E extends ...> - java

I have two classes like this
public class Wire<E extends Electricity> implements Connection<E> {
private ArrayList<Inlet<E>> outlets = new ArrayList<Inlet<E>>();
public void outputToAll() {
for (Inlet<E> inlet : outlets){
inlet.addToStore(new Electricity(amountPer));
}
}
}
and
public abstract class Inlet<E> {
private E store;
public void addToStore(E inputObj){
this.store.add(inputObj);
}
}
Inlet doesn't have any errors, but Wire gives me the error that
The method addToStore(E) in the type Inlet is not applicable for the arguments (Electricity)
However, since in outputToAll E must extend electricity, so Inlet is at least Inlet, why does passing an Electricity object to addToStore not work?
And if the compiler isn't smart enough to know that this will work, what is a good workaround?

You don't need the Wire class to be generic for what it seems like you want to do.
If you just have:
public class Wire implements Connection<Electricity> {
private ArrayList<Inlet<Electricity>> outlets = new ArrayList<Inlet<Electricity>>();
public void outputToAll() {
for (Inlet<Electricity> inlet : outlets){
inlet.addToStore(new Electricity(amountPer));
}
}
...
}
This class will (likely, as I can't see the rest of it) work for subclasses of Electricity too, due to the Liskov substitution principle.

Related

Java bounded wildcards in C#

I'm stuck with this problem for several hours. I'm trying to find an equivalent method for C#.
Java, works:
public class Main
{
public static void main(String[] args)
{
ArrayList<BaseList<? extends Base>> list = new ArrayList<>();
list.add(new DerivedList());
}
}
public class BaseList<T extends Base>
{
}
public class Base
{
}
public class DerivedList extends BaseList<Derived>
{
}
public class Derived extends Base
{
}
I need an equivalent method for ArrayList<BaseList<? extends Base>> in C#. I hope someone help me.
And is it posible in C# to wildcard your variables??
You cannot do that exactly as you describe, but there are workarounds. One is mentioned in another answer, another is to use interface instead:
public class Main
{
public static void main(String[] args)
{
var list = new List<IBaseList<Base>>();
list.Add(new DerivedList());
}
}
// note "out" here
public interface IBaseList<out T> where T : Base {
}
public class BaseList<T> : IBaseList<T> where T : Base {
}
public class Base {
}
public class DerivedList : IBaseList<Derived> {
}
public class Derived : Base {
}
C# uses runtime type reification, whereas Java uses type erasure. Which means that in Java, ArrayList<Foo> is the same class as ArrayList<Bar> at runtime. This is not the case in C#, so you can't just throw away the type parameter like that.
You can try to work around that like this:
public abstract class BaseList
{
}
public class BaseList<T> : BaseList
where T : Base
{
}
Then use a List<BaseList>

Checking `instanceof` while iterating through a loop

I have class structure where
public abstract class AbstractBuilding implements some non-relevant
interfaces for this question.
public abstract class AbstractAnimalBuilding extends AbstractBuiling
And small number of classes following this structure:
public class AnimalBuildingA extends AbstractAnimalBuilding
public class AnimalBuildingB extends AbstractAnimalBuilding
public class AnimalBuildingC extends AbstractAnimalBuilding
public class AnimalBuildingD extends AbstractAnimalBuilding
In a totally separate class I have the following method:
#FXML
private Button btnAnimalBuildingA;
#FXML
private Button btnAnimalBuildingB;
#FXML
private Button btnAnimalBuildingC;
#FXML
private Button btnAnimalBuildingD;
for (AbstractAnimalBuilding animalBuilding: animalBuildings){
if (animalBuilding instanceof AnimalBuildingA) {
changeButtonDisplay(btnAnimalBuildingA)
} else if (animalBuilding instanceof AnimalBuildingB){
changeButtonDisplay(btnAnimalBuildingB)
} else if (animalBuilding instanceof AnimalBuildingC) {
changeButtonDisplay(btnAnimalBuildingC)
} else if (animalBuilding instanceof AnimalBuildingD){
changeButtonDisplay(btnAnimalBuildingD)
//Do something specific here
}
}
private void changeButtonDisplay(Button buttonToChange){
button.setVisible(true);
}
Where animalBuildings is a Set<AbstractAnimalBuilding> containing any combination of AnimalBuildingX's.
Assuming the structure at the top needs to be kept (eg, AnimalBuildingX HAS to extend AbstractAnimalBuilding), what would be a better approach than the multiple if-then-else statements in determining what kind of building animalBuilding is?
Would it feasible to simply create a new Interface as outlined in this question and have each AnimalBuildingX implement it while still extending AbstractAnimalBuilding or is there a way I can do it using the structure I currently have.
This is difficult to answer in general without more context.
One possibility is to create an abstract method in AbstractBuilding and implement it differently in the subclasses.
Another possibility is to use the visitor pattern.
It depends on the action you want to take on behalf of the derived class type. If an action has to be taken which can be perfomed without the need, that the calling class knows the concrete implementation of AnimalBuilding the interface method is appropriate. This usually is the case if you can find a common method description which is implemented differently for each concrete class (e.g. getName()).
If you need to do specific actions dependent on the concrete class (e.g. AnimalBuildingA differs from AnimalBuldingB), you can implement the visitor pattern:
public abstract class AbstractAnimalBuilding {
...
public abstract void accept(AnimalBuildingVisitor v);
}
public interface class AnimalBuildingVisitor<T> {
public T visit(AnimalBuildingA a);
public T visit(AnimalBuildingB b);
...
}
The implementation of the accept-method usually is the one liner
return v.visit(this);
Then you create an implementation of the Abstract visitor which does the work you want to perform in the loop. The loop then looks like this
ConcreteAnimalBuildingVisitor v;
for (AbstractAnimalBuilding animalBuilding: animalBuildings)
animalBuilding.accept(v);
This way, the concrete class "identifies" itself to the concrete visior which then can perform the appropriate action.
You can keep your current structure and achieve what you desire by using generics:
First we need to define a generic handler interface:
public interface AnimalBuildingHandler<T extends AbstractAnimalBuilding> {
void handle(T type);
}
And then, in your own custom class, we can implement specific function for each types:
/* Here you can define all */
public void handleAnimalBuildingA(AnimalBuildingA animalBuildingA) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingA);
}
public void handleAnimalBuildingB(AnimalBuildingB animalBuildingB) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingB);
}
And then, we can create a magic handler class that implements the above AnimalBuildingHandler interface by mapping handlers to types just like this:
private Map<Class<? extends AbstractAnimalBuilding>, AnimalBuildingHandler<? extends AbstractAnimalBuilding>> handlersMapping;
{ /* default instance initializer */
handlersMapping = new HashMap<>();
handlersMapping.put(AnimalBuildingA.class, new AnimalBuildingHandler<AnimalBuildingA>() {
#Override
public void handle(AnimalBuildingA type) {
handleAnimalBuildingA(type);
}
});
handlersMapping.put(AnimalBuildingB.class, new AnimalBuildingHandler<AnimalBuildingB>() {
#Override
public void handle(AnimalBuildingB type) {
handleAnimalBuildingB(type);
}
});
}
#Override
public void handle(AbstractAnimalBuilding type) {
AnimalBuildingHandler abh = handlersMapping.get(type.getClass());
abh.handle(type);
}
And finally, the test method:
public <T extends AbstractAnimalBuilding> void test() {
List<T> allAnimalBuildings = new ArrayList<>();
allAnimalBuildings.add((T) new AnimalBuildingA());
allAnimalBuildings.add((T) new AnimalBuildingB());
for (AbstractAnimalBuilding aab : allAnimalBuildings) {
handle(aab);
}
}

How to apply more constraints on an interface declaration in Java?

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
}

avoid raw generic type in inheritance/delegation structure

My problem is quite complex and hard to explain, so I built a smaller example. It's still complex, but let me try my best...
You can download the full example here: https://mega.co.nz/#!400lSbqa!NoyflWYk6uaQToVDEwXyn22Bdcn_6GdTxB6dPUfU5FU
I recommend importing this into your favourite IDE and playing around.
Imagine you are programming a multiplayer game. It is supposed to have a world with entities. The code should be split into server, client, and shared stuff.
Each of my entities consist of 3 files:
the base, which contains shared code and resources like the name
the clientside, which derive the base and contain rendering etc.
the serverside, which also derive the base and contain network events etc.
Because I can only derive from one class but want my client/server entities to have some shared code too, I tried it with a delegation-style structure. Let's name the actual entity [default], mark interfaces with *'s and extends / implements with <-
- *BaseEntity*
- [DefaultBaseEntity] <- *BaseEntity*
- *ClientEntity* <- *BaseEntity*
- [DefaultClientEntity] <- [DefaultBaseEntity], *ClientEntity*
- *ServerEntity* <- *BaseEntity*
- [DefaultServerEntity] <- [DefaultBaseEntity], *ServerEntity*
This way, I can also duck-typing-access The server/client specific implementations plus the base implementations with only holding ClientEntity/ServerEntity.
Now I want to program a world containing those entities. The world's code shall also be split into three parts and be generic to either contain server or client entities.
package base;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseWorld<E extends BaseEntity> {
private List<E> entities;
public BaseWorld() {
entities = new ArrayList<>();
}
public void addEntity(E entity) {
entity.setWorld(this);
entities.add(entity);
}
public List<E> getEntities() {
return entities;
}
public void doStuffWithBuilding(E entity) {
entity.doBasestuff();
}
}
package client;
import base.BaseWorld;
public class ClientWorld extends BaseWorld<ClientEntity>{
}
package server;
import base.BaseWorld;
public class ServerWorld extends BaseWorld<ServerEntity> {
}
As you see, I am giving my entities a backreference to the world they are in. And this contains the actual problem.
Here's a look into the corresponding entity code:
package base;
public class DefaultBaseEntity implements BaseEntity {
private BaseWorld world;
#Override
public void doBasestuff() {
System.out.println("I am base entity");
}
#Override
public void setWorld(BaseWorld world) {
this.world = world;
}
#Override
public BaseWorld getWorld() {
return world;
}
}
Now this works, but BaseWorld is a raw type. Obviously, every IDE starts to complain. I also do not want to suppress warnings.
I cannot use wildcard types like BaseWorld<? extends BaseEntity> either, because they produce compile errors, when I call world methods like doStuffWithBuilding():
package client;
import base.DefaultBaseEntity;
public class DefaultClientEntity extends DefaultBaseEntity implements ClientEntity {
#Override
public void doClientstuff() {
System.out.println("I am client");
getWorld().doStuffWithBuilding(this);
}
}
The method doStuffWithBuilding(capture#1-of ? extends BaseEntity) in
the type BaseWorld is not
applicable for the arguments (DefaultClientEntity)
Is there any solution to this? I tried removing the set/getWorld() from the base interface and adding it to client and server, but that was very clunky and causes a lot of repitition because of the delegation.
You can probably get around this by parameterizing DefaultBaseEntity:
public class DefaultBaseEntity <E extends BaseEntity>
implements BaseEntity<E> {
private BaseWorld<E> world;
// ...
}
public class DefaultClientEntity extends DefaultBaseEntity<ClientEntity>
implements ClientEntity {
// ...
}
Observe that DefaultClientEntity does not need to be parameterized (at least not for this purpose), even though its superclass is.
Update:
Furthermore, you can perform analogous parameterization with your interfaces:
interface BaseEntity <E extends BaseEntity> {
public void setWorld(BaseWorld<E> world);
// ...
}
interface ClientEntity extends BaseEntity<ClientEntity> {
// ...
}
The example DefaultBaseEntity code above is updated to implement that generic BaseEntity interface.
You will have to put the right type parameters everywhere:
public interface BaseEntity<E extends BaseEntity> {
public void doBasestuff();
public void setWorld(BaseWorld<E> world);
public BaseWorld<E> getWorld();
}
public interface ClientEntity<E extends BaseEntity> extends BaseEntity<E> { ... }
public class DefaultBaseEntity<E extends BaseEntity> implements BaseEntity<E> {
private BaseWorld<E> world;
#Override
public void doBasestuff() {
System.out.println("I am base entity");
}
#Override
public void setWorld(BaseWorld<E> world) {
this.world = world;
}
#Override
public BaseWorld<E> getWorld() {
return world;
}
}
public class DefaultClientEntity extends DefaultBaseEntity<DefaultClientEntity>
implements ClientEntity<DefaultClientEntity> { ... }

Using Generalization properly

Suppose you have the following Interfaces
public interface Action {
public State execute(State state);
}
public interface State {
public Collection<Action> getPossibleActions();
}
And this method
public static Collection<State> getAllSuccessorStates(State state){
Collection<State> allSuccessors = new HashSet<>();
for (Action action: state.getPossibleActions()){
State successorState = action.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
A Concrete State could be for example a Chessboard and an Action the movement of a Piece on the board. Obviously the Chess-Actions need to know the concrete State class:
public class ChessAction implements Action {
#Override
public ChessState execute(ChessState state) {...}
}
Which is ofcourse not an allowed way of overriding execute. What would be the correct way of implementing this, so you can have concrete Actions, that operate on concrete States, which you can give as Arguments to getAllSuccessorStates?
I thought about Generics and also got answers pointing to Generics, but that brings about new Problems. If i write the Action class like this:
public interface Action<E extends State> {
public E execute(E state);
}
i will have the following Problem with ChessState class:
#Override
public Collection<Action<State>> getPossibleActions() {
Collection<Action<State>> actions = new ArrayList<>();
actions.add(new ChessAction());
return actions;
}
the line Actions.add causes the following error: The method add(Action) in the type Collection> is not applicable for the arguments (ChessAction)
Now i could declare Actions as
Collection<Action<ChessState>> actions = new ArrayList<>();
but that wont be a permitted return type.
You can use generics (needs java 1.5 or above):
public interface Action<T extends State> {
public T execute(T state);
}
public class ChessAction implements Action<ChessState> {
#Override
public ChessState execute(ChessState state) {...}
}
Hope that helps.
i found a satisfactory Solution now, which works correctly, doesnt need instanceof and yields no compile warnings:
public interface Action<E extends State<?>> {
public E execute(E state);
}
public interface State<E extends Action<?>> {
public Collection<E> getPossibleActions();
}
public static <A extends Action<S>, S extends State<A>> Collection<S> getAllSuccessorStates(S state){
Collection<S> allSuccessors = new HashSet<>();
for (A localAction: state.getPossibleActions()){
S successorState = localAction.execute(state);
allSuccessors.add(successorState);
allSuccessors.addAll(getAllSuccessorStates(successorState));
}
return allSuccessors;
}
Example of using getAllSuccessorStates (i forgo the implementation Details of the concrete classes here, but the Point should be apparent. You can use the method getAllSuccessorStates with any concrete State class, get Instances of this class in return collection and use them)
public class TestState implements State<TestAction> {...}
public class TestAction implements Action<TestState> {...}
public static void main(String[] args) {
TestState initialState = new TestState("1");
Collection<TestState> allSuccessorStates = getAllSuccessorStates(initialState);
for (TestState state: allSuccessorStates){
System.out.println(state.getStateStr());
}
}
This Question arose from the book "AI-A modern approache" by Stuart Russel and Peter Norvig, in case somebody who reads this book has the same Problem and searches for solutions. In the book the Action and State methods are inside a Problem Class, but i think in this way the OO-design is better.
Well, ChessState must have the same signature of execute as in the Action interface. If you require that ChessAction.execute accept only ChessState, you can write :
public class ChessAction implements Action {
#Override
public State execute(State state)
{
if (!(state instanceof ChessState))
throw new SomeException ();
ChessState cs = (ChessState) state;
...
}
}
You need to implement the same inherited method, and it will work since State is a super class for CheesState.
public class ChessAction implements Action {
#Override
public State execute(State state) {...}
}
Inside the execute method, you can use polymorph method (define in State and redefined ChessState), or you can cast to ChessState (ChessState s = (ChessState) state;), then use it as you need

Categories