Interface referencing an inner class of its implementation - java

I am refactoring a piece of code and I have to made a method (lets call it myMethod) in one class (let's call it TestImpl) from private to public. Therefore, I try to add this method to its interface (ITest).
However, the problem is that a parameter of the method references to an inner class of TestImpl. i.e. something like:
myMethod (TestImpl.NewType var1, ...)
This seems a bit weird to me as the interface references to its own implementation. What is the best solution here? Or, is it really a problem?

As I understand it's static class, then it shouldn't be a problem. However, I think it's better to move that NewType out of TestImpl or even create new interface to generalize this NewType

It violates the DI principles, Interface should not have nay compile dependencies to its implementations. NewType should be extracted as a interface or class to outside.

Related

Methods That Return an Object of an Interface Type

All beginners like myself, always get confused to see a method returns an object of an interface type, because interfaces have abstract methods, thus cannot be instantiated.
I finally figured out a way to understand this:
((when we say that a method returns an object of an interface type, we are actually implicitly saying that the method in fact returns an object/instance of some class that implements that interface, but in most cases that class is unknown because it is declared as anonymous in the implementation of the method. Thus, we refer to the returned object as being of that interface type.)).
Is this explanation correct ?
"...when we say that a method returns an object of an interface type, we are actually implicitly saying that the method in fact returns an object/instance of some class that implements that interface..." - It is correct, but we are saying it explicitly.
The second part of your definition is quite not correct, as #Jon Skeet pointed out. Applying anonymous class in the implementation is a very specific case. Generally, returning an interface gives you more freedom:
It is possible to change implementation of the method to return another object that implements the same interface, without changing code that uses this method.
You leave possibility for extending classes to override the method, so that it returns another object that implements the same interface. Here you can actually change the return type. If method of the base class returned concrete class, e.g., ArrayList, overridden method would have to also return ArrayList or its subclass.
The rule of thumb is the following. If concrete class implements an interface and there is no benefit in returning a concrete class object, e.g., ArrayList, return an interface - List, Collection. This will enhance maintainability of your code, i.e., the code will be easier to change in future.
It's my birthday at the end of this month, so I've added a new method to all my friends and family:
public Present givePresent{
//code to select an appropriate and sufficiently expensive present
return present;
}
There's two things I could do here. I could write a Present class and ensure that all possible presents extend it. But we could run in to all sorts of problems here: BatmanComic already inherits from ComicBook for example, so we'd have to move further and further up the tree until Present is basically indistinguishable from Object. The other way is to look at what is actually happening here. I'm looking to receive something that fits in to a specific category and, in short, Java has two ways of doing that. Inheritance and Interfaces. Creating Present as an interface is achieving exactly the same goal as creating it as an abstract superclass but avoids all problems of multiple inheritance. This way all I have to do is write an interface:
public interface Present{
}
and make sure all the socks and books and whatever implement that.

Refactoring and avoiding code duplication

I've ran into a problem that is new for me. Basically, someone else has already written a class A. The important parts looks like this
class A{
// some instance variables
public A(){
// Calls methods
build();
// Calls more methods
}
private build(){
item = makeItem();
anotherItem = makeAnotherItem();
// more code
}
private makeItem(){
// Does some things and calls updateItem()
}
private updateItem(){
// Does some things with instance variables of class A
// and calls yet another method in class A.
}
My problem is that build() does exactly what I need, but I need it in another class. Now here are the problems:
class A does a whole lot more than the things I've written, and so I cannot create an object of it. It would be pointless.
I've tried copying the build() method for my class B. However, build() uses other methods. And so I have to copy them as well and of course they call other methods and use instance variables declared in some other methods. Basically, I would have to copy 200 rows of code.
I'm guessing this problem actually has a name but I do not know what it's called and have therefore searched some basic terms only. What can I do to use build() in my class B?
You use the code of the build method in two classes but inheritance is not useful? Then you can reuse the code of the build method with composition. (hint Favor Composition over Inheritance) Create a new class C, which contains the build method. The class C is used by the classes A and B via composition. They delegate to the build method of the class C.
See the refactoring method of Martin Fowler.
https://sourcemaking.com/refactoring/smells/duplicate-code
also see
https://sourcemaking.com/refactoring/replace-inheritance-with-delegation
Always refactor in small steps. e.g. Put stuff together that belongs together, perhaps there is a neccessity for another class C which contains makeItem, makeAnotherItem and the corresponding instance variables. There is no general answer and it depends on how your code exactly looks like
first of all if build() in class A is using other private methods of A, that smells like you will need class A itself.
One option could be to create abstract class containing the common methods (including the build method), and extend this abstract class by class A and B. that way you will not have duplicate code
If for some reason you don't want to touch class A, I suggest you create an interface like :
public interface Builder{
void build()
}
and then implement this interface by your class B, and also extend class A so that you have implementation of the build method.
public class B extends A implements Builder{
// build() of class A will be used
// do other staff
}
In doing so, there is no change to class A at all (this might be desired if it is legacy code or something) + Builder can be used as a type in API you want to expose.

How to call a singleton method from a Java POJO?

I wondered if it would be possible to call from a POJO a singleton bean's method through its interface. Maybe this idea is wrong or the architecture...but this is what I would like to accomplish if it is possible, because this is the architecture of the project.
I notice that when I call getInstance() (the method from the singleton's interface) from the POJO, there is an error occuring, telling me that the method has to be static, but if I make the method static, then I have to write the implementation in the interface and I can't get the singleton instance.
Your current approach with the interface is flawed. By default, all methods in an interface (up until Java 8) are static, and are implemented by instance methods in the implementing class.
This means, this is not an option. After all, you'll need to run the method to create an instance, meaning, you don't have an instance yet, so you have no instance to call it on.
Putting the same static method in an abstract class you extend, is also not a solution: a super class should never be aware of it's subclasses. If it is a static method (which it needs to be), you need to keep it in the class itself: a static method in an abstract class can (through an anonymous implementation of the abstract class) return an instance of the abstract class, but this is not the same as an instance of the subclass, which is what you are looking for.
In order to use this method for the subclass, you will need to inherit it from the super class. But, it will still return an instance of the super class. You'll need to overwrite the method in the subclass by the correct one, so the best solution is to add it straight in your Singleton class.
You are not allowed to have static methods in your interfaces (at least not until Java 8). Something like this is not allowed:
MyInterface var = new MyImplementingClass();
var.staticMethod();
Just remove the interface and do your static method call against the class where the static method resides.
Search a bit for the singleton pattern - the 'standard' way to do this involves classes and not interfaces, so rethink your design.
The idea seems to be wrong. A static method is always at a class level and hence you can never declare a method as static in a Java interface(you can do this in Java 8). However, this seems like the wrong design. If you really want to do something like this -
1)Make the Interface an abstract class.
2)Create a static method called getInstance();
3)Extend the abstract class in your POJO singleton class.
Hope this helps!!

java abstract class inheritance

i have an abstract class,this class is extended in her subclasses:
i implementend one method on this abstract class and i made the other method abstracts
the implemented method is a general method that every subclass object has to access on it.So i decided to implement it on the abstract class,avoid implementing the same method on each subclass.
little example:
public abstract class Foo{
//plus constructor and other stuff.
public abstract void differentTypeOfImplementation();
public void doSomething(Foo foo){
//do something with the generic Foo object passed
}
}
i want your opinion on this type of implementation,
regards.
This question is probably too open ended, but your solution is perfectly fine.
The alternative is that you can make an Interface with differentTypeOfImplementation(), and then a utility class with doSomething. That way, your subclasses can also extend from other classes. However, if subclasses may occasionally override doSomething, or if doSomething require accessing internal states of the object, then what you have is perfectly valid.
Implementing a method in an abstract class is very much valid and acceptable design. If this method implementation is necessary for all its subclasses then this is the way to go. In your example however - the signature of the method makes it little fishy - it looks like you are not using the super class state in any way . That means you could as well declare this method as static.

Java method override/interface problem

I have
interface FooI
class FooA implements FooI
class FooB implements FooI
class FooC implements FooI
I wrote a class "Handler" that has the following methods
static double handle(FooA f)
static double handle(FooB f)
static double handle(FooI f)
and I have a function like the following:
void caller(FooI f)
{
Handler.handle(f);
}
with f just being known as a class implementing FooI. However f is an instance of FooA
Instead of calling the method for FooA, the method for FooI is called.
When I use f.getClass().getName() I get the correct class name (FooA).
I am confused because I expected the best-suited method to get called, namely the one for FooA.
I wanted to use the FooI method as a fallback to handle classes that could be implemented later, and I also want to handle f without having one big function where I am doing instanceof checks for all currently known classes implementing my interface.
What would be a good approach to do this?
Overload resolution is done at compile time rather than execution time in Java. The signature was picked based on the compile-time type of your variable. Only overrides are determined at execution time.
A common solution for this in languages like Java is to use double dispatch and the visitor pattern.
Personally I'm not a huge fan of this. I prefer to try to design my way around it. That's not always possible, of course, but it's worth at least attempting.
You expect that the JVM seaches for the best fitting method at run time but that doesn't happen, actually. Instead the method to call is selected during compile time, when the only known information is that f is a class that implements FooI.
The best approach for that problem, the one that avoids the instanceof checks, might be moving the "handle" method into those classes FooA, FooB, FooI.
I don't know exactly what your design is, but might the 'handle' functionality be better placed in your concrete FooI implementations?
Java resolves which method to call at compile time using the reference type, which in your example is FooI - if you think about it this makes sense as the reference type is all it really has to go on at compile time.
Your Handler class doesn't handle(FooI f) and so as far as the compiler is concerned there is no valid handle method to call.
you should not use a static method for that, static methods obey to other rules than non final instance methods
You could transform your interface into an abstract class, with a handler implementation. Then you implement it, and FooA and FooB overrides it

Categories

Resources