I'm having an issue with interfaces, i have a class that implements an interface which i expect to fire after a network response of 200. My interface is not called (how do i hook it to my NetworkrequestClass?)
//My class
public class MyClass extends AnotherClass implements MyDesiredListener{
private void myMethod(){
if (!value) {
NetworkCallClass.specificRequest(); //To call onDesiredLoadedData
}
}
#Override
onDesiredLoadedData(){
//Update Value
}
}
//My inteface in its own file
interface MyDesiredListener{
onDesiredLoadedData();
}
I'm not sure if I understand you correctly, but if I did here you are:
public class FirstClass implements MyInterface {
public void method() {
NetworkCallClass clazz = new NetworkCallClass(this);
clazz.specificRequest();
}
#Override
public void onDesiredLoadedData() {
// here you are your callback
}
}
public class NetworkCallClass {
MyInterface _callbacks;
public NetworkCallClass(MyInterface callbacks) {
_callbacks = callbacks;
}
public void specificRequest() {
// code
if (networkResponse == 200) {
_callbacks.onDesiredLoadedData();
}
}
}
Related
I have a class called Router that takes care of interfacing with Retrofit. So in here are all the core methods. Then i have an abstract class called ConfigurableRouter (that extends Router), that allows me to configure my router. Now i want that i can create children of the ConfigurabelRouter (In fact it is an abstract class) with different defults values.
This is an example how it works:
Router.configure(M_Rout.class)
.setPath("close-pi")
.setParams(params)
.setRequestMethod(Router.RequestMethod.POST)
.setIsAuthRequested(true)
.setCallback(new RequestResponse() {
#Override
protected void onSuccess(HashMap<String, String> responseItems) {}
#Override
protected void onGeneralError(int responseCode) {}
#Override
public void onFailure() {}
})
.sendRequest(getActivity());
This is how the Router.configure() methods work:
public static ConfigurableRouter configure(Class<? extends ConfigurableRouter> aClass){
ConfigurableRouter configurableRouter = null;
try {
configurableRouter = aClass.newInstance();
//obj is a newly created object of the passed in type
} catch (Exception ignored) { }
return configurableRouter;
}
And this is an example of a ConfigurableRouter method:
public ConfigurableRouter setParams(HashMap<Stthring, Object> params){
super.setRouterParams(params);
return this;
}
And this is the M_Router class:
public class M_Rout extends ConfigurableRouter {
#Override
public String setBasepath() {
return "www.xxxxxxx.xx/";
}
#Override
public String setInDebigBasePath() {
return "www.debugxxxxxxx.xx/";
}
#Override
public boolean isDebugging() {
return false;
}
#Override
public RequestMethod setDefultRequestMethod() {
return RequestMethod.POST;
}
#Override
public RequestResponse setDefultResponse() {
return new RequestResponse() {
#Override
protected void onSuccess(HashMap<String, String> responseItems) {
Log.d("RouterLog", "PigSUCSESSSpig");
}
#Override
protected void onGeneralError(int responseCode) {
}
#Override
public void onFailure() {
}
};
}
#Override
public ConfigurableRouter setAuthToken(String authToken) {
return super.setAuthToken("tokenExample");
}
public void setIsAuthRequested(boolean b){
//
}
}
Now my problem is that i cannot acces the non-overriden methods in M_Router class, like setIsAuthRequested(), that is in the first snippet. I have no idea how i can do.. tried in different ways but nothing. How can i do?
public abstract class Person {
abstract void sayName();
}
which has two implementations:
public class LoudPerson extends Person {
void sayName() {
System.out.println("I yell my name!!");
}
}
and
public class RegularPerson extends Person {
void sayName() {
System.out.println("I will say my name");
}
void givesBusinessCard() {
// whatever
}
}
Now, if you create a method like this:
public void handlePerson(Person person) {
}
you will be able to call the sayName() method on it, because no matter what type of Person it is, it will always have an implementation of sayName()
Now, let's say you want to pass an instance of RegularPerson, and call the givesBusinessCard(), this won't immediately work.
Even if all you ever pass as parameters are of type RegularPerson, the JVM running the code doesn't (can't) know this
Someone else could create other subclasses, and change that line of thought.
As far as the JVM knows, it's just a Person, and all Person provides is the sayName() method.
Let's say you need to be able to call the givesBusinessCard() method, you have 3 options.
Alter the method you call. If you need givesBusinessCard() to be called, you know it's a RegularPerson, so you can say:
public void handlePerson(RegularPerson person) {
}
Alter your abstract class, add the method there, and provide either a failing or an empty implementation of the method in LoudPerson
public abstract class Person {
abstract void sayName();
abstract void givesBusinessCard();
}
and
public class LoudPerson extends Person {
void sayName() {
System.out.println("I yell my name!!");
}
void givesBusinessCard() throws UnsupportedOperationException {
throw new UnsupportedOperationException("not needed here");
}
}
or
public class LoudPerson extends Person {
void sayName() {
System.out.println("I yell my name!!");
}
void givesBusinessCard() {
}
}
Cast your person to RegularPerson before calling it, but make sure to do an instance check:
public void handlePerson(Person person) {
// ..
if ( person instanceof RegularPerson ) {
RegularPerson p = (RegularPerson)person;
p.givesBusinessCard();
}
// ..
}
I have below set of interfaces and classes.
Note the doSomething method. It has to check for the instance of the object before calling the interface method on it. I would like to avoid that, as it involves changing this method whenever a new Vehicle is added. What is the best way of doing this in Spring?
class SomeService {
#Autowired
VehicleRepairService<Car> carRepariService;
#Autowired
VehicleRepairService<Truck> truckRepairService;
public void doSomething(String vehicleId) {
Vehicle vehicle = getVehicle(vehicleId);
if(vehicle instanceof Car) {
carRepairService.repair(vehicle);
} else {
truckRepairService.repair(vehicle);
}
}
}
interface VehicleRepairService<T extends Vehicle> {
void repair(T vehicle);
}
class CarRepairService implements VehicleRepairService<Car> {
#Autowired
SomeDependency some;
void repair(Car vehicle) {
.......
}
}
class TruckRepairService implements VehicleRepairService<Car> {
#Autowired
DifferentDependency different;
void repair(Truck vehicle) {
.......
}
}
Since none of the answers has a generic solution. Spring allows to inject all implementations of a type. The solution below is not tested I wrote it in a text editor. It can be improved by making VehicleRepairService an abstract class and use for example ResolvableType retrieve the generic type in this abstract class. Than it is not necessary anymore to implement the getType method in every instance.
class SomeService {
#Autowired
private List<VehicleRepairService> vehicleRepairServices;
public void doSomething(String vehicleId) {
Vehicle vehicle = getVehicle(vehicleId);
for(VehicleRepairService vehicleRepairService:vehicleRepairServices){
if(vehicle.getClass().equals(vehicleRepairService.getType())){
vehicleRepairService.repair(vehicle);
}
}
}
public Vehicle getVehicle(String id){
return new Truck();
}
}
interface VehicleRepairService<T extends Vehicle> {
void repair(T vehicle);
Class<T> getType();
}
class CarRepairService implements VehicleRepairService<Car> {
public void repair(Car vehicle) {
}
#Override
public Class<Car> getType() {
return Car.class;
}
}
class TruckRepairService implements VehicleRepairService<Truck> {
public void repair(Truck vehicle) {
}
#Override
public Class<Truck> getType() {
return Truck.class;
}
}
In general where you have instanceof together with switch or if .. else if ..s you could think about using the Visitor pattern. For your code it would mean something like this:
interface Vehicle
{
public interface Visitor<T>
{
T visit(Car car);
T visit(Truck truck);
}
<T> T accept(Visitor<T> visitor);
}
class Car implements Vehicle
{
#Override
public <T> T accept(Visitor<T> visitor)
{
return visitor.visit(this);
}
};
class Truck implements Vehicle
{
#Override
public <T> T accept(Visitor<T> visitor)
{
return visitor.visit(this);
}
};
You can then on the places where you need a distinction between the specific instances create a new Visitor, either inline or as separate class:
Vehicle.Visitor<Void> repairVisitor = new Vehicle.Visitor<Void>()
{
#Override
public Void visit(Car car)
{
carRepairService.repair(car);
return null;
}
#Override
public Void visit(Truck truck)
{
truckRepairService.repair(truck);
return null;
}
};
vehicle.accept(repairVisitor);
Please note that I made the visitor generic. You could then also have Visitors returning something.
I have few classes that implements some interface. Now I want to create new class, which can extend one of them, based on runtime calculation while using interfaces methods. Let's talk in code:
public interface Interface {
public void doSomething();
}
public class A implements Interface {
#Override
public void doSomething() {
System.out.println("hello");
}
}
public class B implements Interface {
#Override
public void doSomething() {
System.out.println("hi");
}
}
These are existing classes, so now I need to do something like this (which is not working of course):
public class C<T extends Interface> extends T {
public void doSomethingElse() {
this.doSomething();
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C<A>();
} else {
c = new C<B>();
}
c.doSomethingElse();
}
}
Is it possible somehow, except the way that I pass argument Interface other to C's constructor and store to class property..?
A class cannot extend from its type parameter.
Use composition instead of inheritance:
public class C<T extends Interface> {
private final T foo;
public C(T foo){
this.foo = foo;
}
public void doSomethingElse() {
foo.doSomething();
}
public static void main(String[] args) {
C<?> c;
if(isSomethingLoaded) {
c = new C<>(new A());
} else {
c = new C<>(new B());
}
c.doSomethingElse();
}
}
You might even not need the type parameter here, but just use the interface type as argument/ member type.
I think it's situations like this which show why we have the rule of favouring composition over inheritance. Consider this solution using composition:
public class Test {
public interface Interface {
void doSomething();
}
public static class A implements Interface {
#Override
public void doSomething() {
System.out.println("Doing A");
}
}
public static class B implements Interface {
#Override
public void doSomething() {
System.out.println("Doing B");
}
}
public static class C implements Interface {
private Interface composedWith;
public C(Interface i) {
this.composedWith = i;
}
#Override
public void doSomething() {
this.composedWith.doSomething();
}
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C(new A());
} else {
c = new C(new B());
}
c.doSomething();
}
}
Personally, I feel this is a clearer and move flexible way of achieving what you are trying to do.
I'm developing an application which builds on a class written by another developer (for which I do not have the source).
I wish to use all of the functionality of said class but also to extend it with additional functionality. Ordinarily to achieve this I would have defined an interface (MyInterface) and have extended the external class (TheirClass) from my own (MyClass) while implementing MyInterface.
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass extends TheirClass implements MyInterface {
public void myMethod1() { ... }
}
public class MyNewClass extends MyClass {
public void MyNewClassMethod() { ... }
}
The problem is complicated by the fact that:
I now wish to create a new class (MyNewClass) which adds additional functionality to MyClass but I don't want my code to be dependent on TheirClass.
I wish to be able to use my class as a parameter to the method of TheirOtherClass.
To combat this I refactored my code to instead use composition over inheritance and implementing TheirClassInterface. This works but requires me to implement many methods and delegate them to theirClassObject (in reality TheirClassInterface contains a very large number of methods).
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass implements TheirClassInterface, MyInterface {
private TheirClass theirClassObject;
public void myMethod1() { ... }
public void theirMethod1() { theirClassObject.theirMethod1(); }
public void theirMethod2() { theirClassObject.theirMethod2(); }
}
public class MyNewClass extends MyClass {
public void MyNewClassMethod() { ... }
}
My question is whether my approach is appropriate in this case and whether it could be improved upon as it seems to me that my code uses an excessive amount of delegation to get the job done.
Many thanks for any guidance anyone can give on this.
Danny
First, as java is a strongly-typed single inheritance language, you cannot escape the delegation.
But you can avoid having to write a lot of delegation CODE, by using a dirty little trick with Proxies and reflection.
Code follows
public interface Interface1 {
void m1();
}
public interface Interface2 {
void m2();
}
public class Class1 implements Interface1 {
public void m1() {
System.out.println(1);
}
}
public class Class2 implements Interface2 {
public void m2() {
System.out.println(2);
}
}
public interface MixinInterface extends Interface1, Interface2 {
}
And this is how the magic happens
package j.with.pseudo.multiple.inheritance;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MixinBuilder {
public static Object buildMixed(Class _interface, Object... impls){
InvocationHandler h = new MixinHandler(_interface.getInterfaces(), impls);
return Proxy.newProxyInstance(MixinBuilder.class.getClassLoader(),
new Class[]{_interface}, h);
}
public static void main(String[] args) {
Class1 o1 = new Class1();
Class2 o2 = new Class2();
MixinInterface almost_like_multiple_inheritance_guy =
(MixinInterface) buildMixed(MixinInterface.class, o1, o2);
almost_like_multiple_inheritance_guy.m1();
almost_like_multiple_inheritance_guy.m2();
}
private static class MixinHandler implements InvocationHandler{
private Class[] interfaces;
private Object[] impls;
public MixinHandler(Class[] interfaces, Object[] impls) {
this.interfaces = interfaces;
this.impls = impls;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
int i=0;
for(Class _interface : interfaces){
if(method.getDeclaringClass().isAssignableFrom(_interface)){
return method.invoke(impls[i], args);
}
i++;
}
// TODO Auto-generated method stub
throw new RuntimeException("Method not found: "+method);
}
}
}
Pretty cool huh? :-)
You can't not-depend on a class if you're extending it; it's like having a definition of Human, which does not depend on the definition of Mammal, your optinos are to rewrite everything in the parent, or depend on it.
Many thanks for the answers so far. I've come up with a solution which I think seems reasonable and allows me to fully encapsulate the foreign class.
At the moment I've returned to the method discussed in the first block of code (repeated and extended below) and am now implementing my MyInterface interface for MyNewClass and delegating all interface operations to a composed object. The object to delegate to is decided at runtime by calling a static method on a Factory.
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass extends TheirClass implements MyInterface {
public void myMethod1() { ... }
}
public class MyNewClass implements MyInterface {
private MyInterface myObject;
public MyNewClass() {
myObject = MyClassFactory.createMyClass();
}
public void myMethod1() {
myObject.myMethod();
}
public void MyNewClassMethod() { ... }
}
Once again, thanks for the ideas. I'm now going to look into them all and see if I can use them to improve my code.
Cheers,
Danny
I have three classes which I have a problem with. They are named: GameScene, StageScene, StageOne. My problem is that I want to implement initialize in StageScene, but still force StageOne to implement it, so that whenever someone uses a StageOne object (stageOne.initialize()), initialize would be run for both StageScene and StageOne. Anyone know how this could be done?
public abstract class GameScene
{
public abstract void initialize();
}
public abstract class StageScene extends GameScene
{
public abstract void initialize()
{
//Some code
}
}
public class StageOne extends StageScene
{
public void initialize()
{
//Some code
}
}
you can do it with a wrapper:
public abstract class StageScene extends GameScene
{
final public void initialize()
{
//your initialization
subInitialize();
}
protected abstract void subInitialize();
}
And in the child class:
public class StageOne extends StageScene
{
public void subInitialize()
{
//Some code
}
}
You could break it into two separate methods
public abstract class GameScene
{
public abstract void initializeScene();
public abstract void initializeStage();
}
public abstract class StageScene extends GameScene
{
public void initializeScene()
{
//Some code
}
}
public class StageOne extends StageScene
{
public void initializeStage()
{
//Some code
}
}