I'm learning Java, I met an example of Closure:
public class Callbacks {
public static void main(String[] args) {
Callee1 c1 = new Callee1();
Callee2 c2 = new Callee2();
MyIncrement.f(c2);
Caller caller1 = new Caller(c1);
Caller caller2 = new Caller(c2.getcallbackReference());
caller1.go();
caller1.go();
caller2.go();
caller2.go();
}
}
interface Incrementable {
void increment();
}
class Callee1 implements Incrementable {
private int i = 0;
#Override
public void increment() {
i++;
print(i);
}
}
class MyIncrement {
public void increment() {
System.out.println("another operation");
}
public static void f(MyIncrement m) {
m.increment();
}
}
class Callee2 extends MyIncrement {
private int i = 0;
public void increment() {
super.increment();
i++;
print(i);
}
private class Closure implements Incrementable {
#Override
public void increment() {
Callee2.this.increment();
}
}
Incrementable getcallbackReference() {
return new Closure();
}
}
class Caller {
Incrementable callbackRegerence;
Caller(Incrementable cbh) {
callbackRegerence = cbh;
}
void go() {
callbackRegerence.increment();
}
}
Comment from the author of the example :
When Mylncrement is inherited into Callee2, increment( ) can’t be overridden for use by Incrementable, so you’re forced to provide a separate implementation using an inner class.
My question is: What? Why can't we? We can override it in the Callee2 class or did I misunderstand the author?
Please explain what he wanted to say with this comment.
You need to have a type of Incrementable as a Caller argument.
You can change this to have the same.
old
class Callee2 extends MyIncrement {
private int i = 0;
public void increment() {
super.increment();
i++;
print(i);
}
private class Closure implements Incrementable {
#Override
public void increment() {
Callee2.this.increment();
}
}
Incrementable getcallbackReference() {
return new Closure();
}
}
New:
class Callee2 extends MyIncrement implements Incrementable {
private int i = 0;
public void increment() {
super.increment();
i++;
System.out.println(i);
}
}
Related
i am trying to programm a Turtle programm in Java following the Visitor pattern.
therefore i have the Visitor:
public interface Visitor {
void visit(Go go);
void visit(Turn turn);
void visit(Call call);
void visit(PenDown pendown);
void visit(PenUp penup);
void visit(Repeat repeat);
void visit(Sequence sequence);
void visit(Subroutine subroutine);
}
and the Abstract Visitor which should implement some of the visit methods:
public abstract class AbstractVisitor implements Visitor {
protected Turtle turtle;
protected AbstractVisitor(Turtle turtle){
this.turtle = turtle;
}
public AbstractVisitor() {
}
public void visit(Turn turn){
turtle.turn(turn.w);
}
public void visit(Sequence sequence){
}
public void visit(Repeat repeat) {
int d = repeat.rep;
for(int i = 0; i<repeat.rep; i++){
for(int s = 0; s<repeat.d.size(); s++){
}
}
}
public void visit(Subroutine subroutine) {
}
public void visit(Call call) {
}
public void visit(PenDown penDown) {
}
public void visit(PenUp penUp) {
}
}
i am Trying to implement the visit(Repeat repeat)
public class Repeat implements Stmt {
public int rep;
public List<Object> d;
public Repeat(int i,Stmt ... s1) {
this.rep = i;
for (int q = 0; q < s1.length; q++) {
d.add( s1[q]);
}
}
#Override
public void accept(Visitor v) {
{
v.visit(this);
}
}
}
this method should get an integer i and some other classes which also implements the Interface Stmt
public interface Stmt {
void accept(Visitor v);
}
like the Class Go
public class Go implements Stmt {
public double dist;
public Go(double d){
if(d<0 ) {
throw new IllegalArgumentException("Die Strecke muss positiv sein");
} this.dist = d;
}
public void accept(Visitor v) {
}
}
So You should be able to hand over an Integer i and as many Classes like Go.
the repeat class should do the visit method for each class handed over and repeat it i times.
Now my Question is how can I check which Class is in the Array of Stmt's I hand over to Repeat? Or is it Wrong how I did the parameters in Repeat?
As a example i want to be able to call
PROG1.accept(visitor)
with
public static final Stmt PROG1 = new Repeat(4, new Go(50), new Turn(90));
I didn't understand completely your problem! But if your question is :
You have an Interface
public interface Stmt {
void accept(Visitor v);
}
and you have two classes implementing this interface each them has a different body for the accept method
public class X implements Stmt{
public void accept(Visitor v) {
//code
}
}
and
public class Y implements Stmt{
public void accept(Visitor v) {
//code
}}
and your question as I understand it is:
HOW do I know which body will be used if I call the accept() method ! is the accept() from X class or the accept() from the Y class ??
Answer :
it depends on your main application, as you know you cannot instantiate an interface!
so it depends on which class you have instantiated!
you will have for example :
Stmt var = new X();
for this one var.accept() will call the body from the X class!
I have a code block like below:
public Interface ISupClass{
void call();
void call1();
...
}
public class NormalClass implements ISupClass{
void call(){
....operations...
}
void call1(){
....operations...
}
...
}
public class DailyClass implements ISupClass{
void call(){
....operations...
}
void call1(){
....operations...
}
...
}
Then I call them from main service like that;
Instances:
private INormalClass dailyClass = new DailyClass();
private INormalClass normalClass = new NormalClass();
Method:
public void call(int type, boolean isDaily){
if(type == 0) {
if(isDaily){
dailyClass.call();
}
else{
normalClass.call();
}
}
if(type == 1) {
if(isDaily){
dailyClass.call1();
}
else{
normalClass.call1();
}
}
...
}
Is there a way to escape from isDaily check in above code block? Or how can I implement it effectively? I have just tried to implement with Java Generics but this doesn't look possible?
I know this looks like related with polimorfizm. But I wonder somethink like about it;
public Interface ISupClass<E>
call(E type)
...
public class NormalClass implements ISupClass<Boolen.FALSE>
...
public class DailyClass implements ISupClass<Boolen.TRUE>
...
public void call(int type, boolean isDaily){
supClass.call(isDaily);
(In case I understood what is the question)
This is the point of using interfaces. Simply do something like this:
public class Example {
public static interface ISupClass {
void doSomething();
}
public static class NormalClass implements ISupClass {
#Override
public void doSomething() {
System.out.println("I am a normal class.");
}
}
public static class DailyClass implements ISupClass {
#Override
public void doSomething() {
System.out.println("I am a daily class.");
}
}
public static void doSomething(ISupClass clazz) {
clazz.doSomething();
}
public static void main(String[] args) {
doSomething(new DailyClass());
doSomething(new NormalClass());
}
}
So, in your case instead of passing boolean isDaily, pass argument ISupClass in call method.
public void call(int type, ISupClass caller) {
caller.call();
}
Now, generics is a totally different story and I am not able to see how it is related to the question.
From what I understand, public void call(int type, boolean isDaily){...} is an orchestrator/mediator method that manipulates the one or the other instance according to the flags received in the parameters.
In this case, why not use a Map<Boolean, INormalClass> to store the two instances in a way where you can retrieve them from a boolean key :
Map<Boolean, INormalClass> map = new HashMap<>();
map.put(Boolean.TRUE, new DailyClass());
map.put(Boolean.FALSE, new NormalClass());
//...
public void call(int type, boolean isDaily){
INormalClass obj = map.get(isDaily);
if(type == 0) {
obj.call();
}
if(type == 1) {
obj.call1();
}
}
You could add default method to the interface:
public interface ISupClass {
default void call(int type) {
if (type == 0) {
call();
} else if(type == 1) {
call1();
}
}
void call();
void call1();
}
It leads you to following code:
public static void call(int type, boolean isDaily) {
if (isDaily) {
dailyClass.call(type);
} else {
normalClass.call(type);
}
}
I have 3 classes which are one child of the other:
Class C ->(subclass of)-> class B ->(subclass of)-> class A.
Every class is real and I want to choose which one to instantiate by a method.
Can I use Factory-method and so factory-pattern to choose which class to create?
thank you.
Yes, the factory method is the way to go in your context. I've provided quick example how to implement it.
import java.util.Scanner;
public class FactoryMethodExample
{
public static void main(String[] args)
{
Scanner reader = new Scanner(System.in);
System.out.println("Enter a letter A, B or C: ");
String input = reader.nextLine();
Factory factory = new ConcreteFactory();
A myClass = factory.getClass(input.charAt(0));
if(myClass != null)
{
myClass.print();
}
else
{
System.out.print("Wrong input");
}
}
}
class A
{
public void print()
{
System.out.print("I'm class A");
}
}
class B extends A
{
#Override
public void print()
{
System.out.print("I'm class B");
}
}
class C extends B
{
#Override
public void print()
{
System.out.print("I'm class C");
}
}
abstract class Factory
{
public abstract A getClass(Character letter);
}
class ConcreteFactory extends Factory
{
#Override
public A getClass(Character letter)
{
if(letter.equals('A'))
{
return new A();
}
else if(letter.equals('B'))
{
return new B();
}
else if(letter.equals('C'))
{
return new C();
}
return null;
}
}
Yes you can use factory method pattern with covarient return types. Here's a sample code.
public class MazeGame {
public Maze createMaze() {
// build the maze here.
return aMaze;
}
public Room makeRoom(final int number) {
return new Room(number);
}
public Wall makeWall() {
return new Wall();
}
// ...
}
public class BombedMazeGame extends MazeGame {
#Override
public Room makeRoom(int number) {
return new RoomWithABomb(number);
}
#Override
public Wall makeWall() {
return new BombedWall();
}
}
I'm trying to get rid of big switch statement from my code and I thought that Strategy pattern based on my existing enum would be nice. The concept is like:
public class MyStrategy {
public MyStrategy() {
Option.Option1.setMethodToExecute(this::action1);
Option.Option2.setMethodToExecute(this::action2);
}
public void executeChoosenMethod(int i) {
Option.values()[i].execute();
// instead of
// switch(convertItoOption()) {
// case Option1:...
// case Option2:...
// }
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1, Option2;
private InvokeAction methodToExecute;
public void setMethodToExecute(InvokeAction methodToExecute) {
this.methodToExecute = methodToExecute;
}
public void execute() {
methodToExecute.execute();
}
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
so I can use it like:
public class StrategyTest {
public static void main(String[] args) {
MyStrategy strategy = new MyStrategy();
//user choose 0 or 1
strategy.executeChoosenMethod(0);
strategy.executeChoosenMethod(1);
}
}
but I don't like this part with Option.Option1.setMethodToExecute(this::action1); since my enum has more and more options and I would like to have all of this inside enum. What would be perfect is something like this:
public class MyStrategy {
public void executeChoosenMethod(int i) {
Option.values()[i].execute();
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1(MyStrategy.this::action1),
Option2(MyStrategy.this::action2);
private InvokeAction methodToExecute;
private Option(InvokeAction method) {
methodToExecute = method;
}
public void execute() {
methodToExecute.execute();
}
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
but this is impossible since enum is static and I don't have access to enclosing instance by MyStrategy.this. I need enum, because I have set of options and it is convenient to use methods like values() or valueOf(), but what I would like to have is single line invoke instead of growing switch.
Do you have any ideas how to achieve sometghing like this or is there any workaround to make this enum constructor call possible Option1(MyStrategy.this::action1) ?
With enums you could implement it like this:
public class MyStrategy {
public void executeChoosenMethod(int i) {
Option.values()[i].execute(this);
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1(MyStrategy::action1),
Option2(MyStrategy::action2);
private InvokeAction methodToExecute;
private Option(InvokeAction method) {
methodToExecute = method;
}
public void execute(MyStrategy s) {
methodToExecute.execute(s);
}
}
#FunctionalInterface
private interface InvokeAction {
void execute(MyStrategy s);
}
}
This uses the fact the with lambdas you can make method references to arbitrary instance methods and call them on a specific instance by passing in the instance as first parameter.
you're right. This isn't possible with enum. But why not just use a good old class:
public class MyStrategy {
public MyStrategy() {
buildUp();
}
public void executeChoosenMethod(int i) {
actions.get(i).execute();
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private List<InvokeAction> actions = new ArrayList<>();
private void buildUp() {
actions.add(this::action1);
actions.add(this::action2);
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
I would like to create an enum containing one attribut, a list of objects extending the same interface or the same abstract class.
The objective is to have a loop on each list of my enum to call methods dynamically.
public interface Regles {
void verifier();
}
public class Regle01 implements Regles {
#Override
public void verifier() {
}
}
public class Regle02 implements Regles {
#Override
public void verifier() {
}
}
public enum ListRegles {
ENUM1(Arrays.asList(new Regle01(), new Regle02())),
ENUM2(Arrays.asList(new Regle01()))
private List<Regles> regles = new ArrayList<Regles>();
ListRegles(List<Regles> r) {
regles = r;
}
}
how can i do this please ?
enum:
public enum ListRegles {
ENUM1(new Regle01(),new Regle02()),
ENUM2(new Regle01());
private List<Regles> regles ;
ListRegles(Regles... regles) {
this.regles = new ArrayList<>(Arrays.asList(regles));
}
public void verify() {
for (Regles regle : regles) {
regle.verifier();
}
}
}
Will call verifier for Regle01 and Regle02
ListRegles.ENUM1.verify();