I have the following classes.
interface interface1() {
void function1()
}
interface interface2 extends interface1() {
void function2()
}
class implementation1 implements interface1 () {
#Override
void function1() {
// Implement
}
}
class implementation2 implements interface2 () {
#Override
void function1() {
// Implement
}
#Override
void function2() {
// Implement
}
}
class Main() {
List<interface1> interfaceList = new ArrayList();
for (interface : interfaceList) {
if (interface instanceOf(interface2)) {
interface.function2();
}
}
}
Could you please tell if there is a way to prevent using instanceOf? I read visitor pattern could be used but I am not getting the exact changes to be done.
Following are the classes after discussing with Alex R below (instanceOf is avoided since it is not recommended, visitor pattern is avoided since it still leads to empty visit functions). Please let me know if this can be done better using other design patterns.
interface interface1() {
void function1();
boolean isFunction2Applicable();
default void function2() {
}
}
class implementation1 implements interface1 () {
#Override
void function1() {
// Implement
}
#Override
boolean isFunction2Applicable() {
return false;
}
}
class implementation2 implements interface1 () {
#Override
void function1() {
// Implement
}
#Override
boolean isFunction2Applicable() {
return true;
}
#Override
void function2() {
// Implement
}
}
class Main() {
List<interface1> interfaceList = new ArrayList();
for (interface : interfaceList) {
if (interface.isFunction2Applicable()) {
interface.function2();
}
}
}
One way to do so is to define some method in the base interface and override it in the sub-interfaces or implementations. In the following example I'm using a default method but you don't have to do so; the method can be abstract and only be implemented in the implementations:
interface I1 {
void function1();
default void execute() {
function1();
}
}
interface I2 extends I1 {
void function2();
#Override
default void execute() {
function1();
function2();
}
}
public static void main(String[] args) {
List<I1> ifaces = new ArrayList<>();
for (I1 iface : ifaces) {
iface.execute();
}
}
Related
I have the following situation:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(DerivedA deriv);
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new DerivedA.Something() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
I want to push usefulMethod and Something upto the Base class so that DerivedB can leverage it. And I want implementations of Something.doSomething to be able to use a derived type, so that it can access derived functionality.
How do I do that?
Attempts
I've tried the following:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(Base deriv);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
but that fails as my anonymous Something doesn't implement doSomething(Base). So trying to use generics:
I tried:
interface Something {
void doSomething(<? extends Base> deriv);
}
but that won't compile due to: "Wildcards may be used only as reference parameters"
I tried:
interface Something {
<T extends Base> void doSomething(T deriv);
}
but that requires me to implement the interface as so:
a.usefulMethod(new Base.Something() {
#Override
public <T extends Base> void doSomething(T deriv) {
}
});
which obviously doesn't allow me access to the derived type?
There are ways I can make it "work" but they're undesirable:
This:
interface Something {
void doSomething(Base deriv);
}
a.usefulMethod(new Base.Something() {
#Override
public void doSomething(Base deriv) {
DerivedA a1 = (DerivedA) deriv;
a1.DerivedBMethodA();
}
});
But that requires me to cast in each implementation, which seems wasteful.
And this:
package com.miurasample.ui.info;
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something<T extends Base> {
void doSomething(T deriv);
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something<DerivedA>() {
#Override
public void doSomething(DerivedA deriv) {
}
});
}
}
but that results in a warning/IDE highlight in usefulMethod of:
"Unchecked call to doSomething(T) as a member of raw type Base.Something"
What's the tersest and "cleanest" way to do this? Is that I'm doing even sane?
It is difficult to say if your design is wrong or not. We dont have full scope of your requirements to assert that, but here is clean non cast approach to what you are trying to do. It does require extra method in your derived classes:
public static void main(String... args) {
DerivedA a = new DerivedA();
a.usefulMethod( new Base.Something<DerivedA>() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
} );
}
public abstract static class Base< T extends Base<T> > {
int data = 0;
protected abstract T getThis();
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something<T> something) {
something.doSomething( getThis() );
}
interface Something< T extends Base<T> > {
void doSomething(T deriv);
}
}
public static class DerivedA extends Base<DerivedA> {
protected DerivedA getThis(){
return this;
}
void DerivedBMethodA() {}
}
public static class DerivedB extends Base<DerivedB> {
protected DerivedB getThis(){
return this;
}
void DerivedMethodB() {}
}
In lectures we were shown this code and told that it creates double dispatch but why does it not create an infinite loop?
If c3po.greet(c4po); calls the TranslationRobot method from TranslationRobot
Why does c5po.greet(c4po); call the AbstractRobot method in CarrierRobot and not the TranslationRobot method and then not call the AbstractRobot method in TranslationRobot which would then call the Abstract Method in CarrierRobot and so on?
What decides whether it calls an AbstractRobot method or not?
AbstractRobot.java
abstract class AbstractRobot extends Robot {
abstract void greet(AbstractRobot other);
abstract void greet(TranslationRobot other);
abstract void greet(CarrierRobot other);
}
CarrierRobot.Java
class CarrierRobot extends AbstractRobot {
...
void greet(TranslationRobot other) {
talk("'Hello from a TranslationRobot to a CarrierRobot.'"); }
void greet(CarrierRobot other) {
talk("'Hello from a CarrierRobot to another.'"); }
void greet(AbstractRobot other) {
other.greet(this);
}}
TranslationRobot.Java
public class TranslationRobot extends AbstractRobot {
...
void greet(TranslationRobot other) {
talk("'Hello from a TranslationRobot to another.'"); }
void greet(CarrierRobot other) {
talk("'Hello from a CarrierRobot to a TranslationRobot.'"); }
void greet(AbstractRobot other) {
other.greet(this);
} }
DispatchWorld.Java
class DispatchWorld {
public static void main (String[] args) {
AbstractRobot c3po = new TranslationRobot();
AbstractRobot c4po = new TranslationRobot();
AbstractRobot c5po = new CarrierRobot();
AbstractRobot c6po = new CarrierRobot();
c3po.greet(c4po);
c5po.greet(c4po);
c4po.greet(c5po);
c5po.greet(c6po);
} }
This produces the output:
Standard Model says 'Hello from a TranslationRobot to another.'
Standard Model says 'Hello from a CarrierRobot to a TranslationRobot.'
Standard Model says 'Hello from a TranslationRobot to a CarrierRobot.'
Standard Model says 'Hello from a CarrierRobot to another.'
I think that the answer why this works and why there is no infinite recursion might be illustrated better if we refactor code a bit by removing all method overloading and putting explicit different names instead:
abstract class Robot
{
void talk(String msg)
{
System.out.println(msg);
}
}
abstract class AbstractRobot extends Robot
{
abstract void greet(AbstractRobot other);
abstract void greetFromTranslationRobot(TranslationRobot other);
abstract void greetFromCarrierRobot(CarrierRobot other);
}
class CarrierRobot extends AbstractRobot
{
void greetFromTranslationRobot(TranslationRobot other)
{
talk("'Hello from a TranslationRobot to a CarrierRobot.'");
}
void greetFromCarrierRobot(CarrierRobot other)
{
talk("'Hello from a CarrierRobot to another.'");
}
void greet(AbstractRobot other)
{
other.greetFromCarrierRobot(this);
}
}
public class TranslationRobot extends AbstractRobot
{
void greetFromTranslationRobot(TranslationRobot other)
{
talk("'Hello from a TranslationRobot to another.'");
}
void greetFromCarrierRobot(CarrierRobot other)
{
talk("'Hello from a CarrierRobot to a TranslationRobot.'");
}
void greet(AbstractRobot other)
{
other.greetFromTranslationRobot(this);
}
}
From the compiler's point of view methods void greet(AbstractRobot other), void greet(TranslationRobot other) and void greet(CarrierRobot other) are 3 obviously different methods which my renaming just highlights.
So a call like c3po.greet(c4po) is actually a call to TranslationRobot.greet which forwards it to other.greetFromTranslationRobot(this) which is TranslationRobot.greetFromTranslationRobot and which obviously should not result in any infinite recursion.
I have interface:
interface operations{
void sum();
}
and I want to have classes:
class matrix implements operations {
#override
void sum(matrix m) {
}
}
class vector3D implements operations {
#override
void sum(vecor3D v) {
}
}
How to do this?
I tried something like this:
interface operations < T > {
<T> void sum(T t);
}
class matrix implements operations<matrix>{
#Override
void sum(matrix m){};
}
}
class vector3D implements operations<vector3D>{
#Override
void sum(vector3D v){};
}
but it doesn't work.
Don't add a type parameters to the interface and the type. Also you should specify the generic parameters of the interface you implement:
interface operations<T> {
void sum(T t);
}
class matrix implements operations<matrix> {
#Override
public void sum(matrix m){
}
}
class vector3D implements operations<vecor3D> {
#Override
public void sum(vecor3D v){
}
}
Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}
Suppose I have two classes A and B where A is a superclass of B. Now, I write a function (override), say funct() in both the classes. Then, if I want to call the funct() in A from an object of B, is it possible?
class A {
public void f() {...}
}
class B extends A {
#Override public void f() { super.f(); }
}
Is that what you want?
If instead you want to call A#f() directly on an instance of type B, you must provide a placeholder function for that:
class B extends A {
#Override public void f() { ... }
public void superF() { super.f(); }
}
new B().f(); // calls B#f();
new B().superF(); // calls A#f();
I have trick such as this situation to operate it in an illogical manner using Flag argument in funct() method :D, like this:
class A {
public void funct(boolean callSuper) {
// avoid using callSuper arg here
}
}
class B extends A {
#Override
public void funct(boolean callSuper) {
if (callSuper) {
super.funct(callSuper);
return;//if return type is void
} else {
//do here the functionality if the flag is false
}
}
}
or
class A {
public void funct() {
}
}
class B extends A {
private boolean callSuper = false;
#Override
public void funct() {
if (callSuper) {
super.funct(); // call A.funct() functionality
setCallSuper(false);
} else {
//do here the functionality of B.funct() if the flag is false
}
}
public void setCallSuper(boolean callSuper){
this.callSuper = callSuper;
}
}
Given classes like
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {...}
}
You ask
Then, if I want to call the funct() in A from an object of B, is it
possible?
So let's take
B b = new B();
b.funct();
A a = b;
a.funct();
((A)b).funct();
The above all do the same thing because of polymorphism and late-binding.
The only way to call the superclass' implementation is to get a reference to that member through the super keyword.
class A {
public void funct() {...}
}
class B extends A {
#Override
public void funct() {
super.funct();
}
}