Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Lets say I have an interface like
interface IMessage
{
void DoSomething();
void DoAnother();
}
Lets say in a big project 100 classes implemented this interface. But if I add a new method to IMessage interface like Foo();
interface IMessage
{
void DoSomething();
void DoAnother();
void Foo();
}
So my other 100 classes which implement this interface has to change. So does something wrong here? Changing all clasess? I hear about Open Close prensible so I used interface but in that situation, what is the logic?
Java 8 introduces "default" methods for interfaces; this means that you can provide a "default" implementation. This allows you to extend existing interfaces without adapting all implementing classes.
But if you are working older versions of Java - you nailed it: then you have to update all your classes.
And hopefully a final edit: modern IDEs are able to generate such "missing" methods for you; and depending on the complexity of what "Foo()" should do ... it might not be so much work in the end.
But there is one other option:
Instead of adding a new method to your existing interface, you could do
interface IMessageV2 extends IMessage {
void Foo();
}
This allows you to decide for each of your classes if you want to "update" the class to implement IMessage or IMessageV2. But of course, for those classes that you change to implement IMessageV2; you have to provide an implementation for any new method in that "new" interface.
The downside of this approach is that sooner or later, your client code will have to deal with objects that implement the V1, V2, V3, ... version of the interface. This can turn nasty, too.
Depends
Do you need this new void Foo() method in all the 100 classes.?
If Yes, then there is no other way and this is not wrong.
But if you want a similar interface but don't want those classes to have the change then write another interface
interface IMessageChild extends IMessage
{
void Foo();
}
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Let's assume that we have an abstract class (let's just call it X) that is inherited by a number of classes (we'll call them A and B for now). Each class that inherits from X does similar, but slightly different things, so while the implementation of each of their public methods might be slightly different, they can all use the same helper functions to avoid duplicating code. However, it makes no sense for any of these helper functions to be accessed by any class that is not a subclass of X.
Furthermore, what if there are a number of helper functions which are only meant to be used inside of classes that extend X, but need to have a slightly different implementation in each class?
Here's an example:
public abstract class X {
public abstract void doStuff();
int helperFunction(int a, int b) {
return a + b;
}
abstract void secondHelperFunction(int x);
}
public class A extends X {
#Override
public void doStuff() {
//do some stuff
helperFunction(a, b);
//so some other stuff
}
#Override
void secondHelperFunction(int x) {
//implementation A
}
}
public class B extends X {
#Override
public void doStuff() {
//do some different stuff
helperFunction(b, a);
//do other stuff
}
#Override
void secondHelperFunction(int x) {
//implementation B
}
}
(This example is obviously very simple, I'm just trying to get my point across)
My question is, what would be the best way to do this? For example, what access modifier should be used for the helper functions? Obviously private isn't an option, since then subclasses wouldn't be able to use it. Default and protected sound like a better choice, but they still allow non-subclasses to use these functions, as long as they are in the same package as X. Would the best solution to this issue then be to enclose X and all classes that inherit from it in their own package, separate from the rest of the program? Or should one perhaps look into another form of abstraction, e.g. interfaces? (Although I cannot think of a way to deal with this using interfaces in particular)
A couple of options for you to consider:
Use protected. You are correct that this does not prevent other classes within the same package from calling the method. But is that really a problem? The idea of a package is to gather related classes together and control the interface through which they are called. Access modifiers are a relatively coarse control mechanism that are designed primarily to help humans avoid errors when coding.
Put the helper functions in a separate class and use composition rather than inheritance. You could still override methods to provide different behaviours. The downside is you will need to pass in any values required. But this isn't necessarily a bad thing as it makes the dependencies clear.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am trying to understand and implement Java Virtual Field Pattern. So far I haven't been able to find many examples or resources on it. This particular resource explains it but not clearly on how it should be implemented. Would someone be able to better explain it or use a new example?
I'll try to explain the pattern using an example similar to the one from the linked mailing list in the linked resource.
Supposed there is a Peeker interface like this:
interface Peeker<T> {
T peek();
T take();
}
You want to your class to implement it but you don't want to implement all method yourself - you just want to delegate all method calls to an existing implementation of Peeker. So you might write your class like this:
class Foo implements Peeker<T>{
private Peeker<T> peeker = new PeekerImpl();
public T peek() {
return peeker.peek();
}
public T take() {
return peeker.take();
}
}
To avoid this boilerplate (especially if you have many other classes that use Peeker in a similar way) you can use the mentioned pattern. You extend the Peeker interface and use default methods to delegate all calls:
interface PeekerView<T> extends Peeker<T> {
Peeker<T> getPeeker();
default T peek() {
return getPeeker().peek();
}
default T take() {
return getPeeker().take();
}
}
Now the interface does all delegation automatically. Your class only has to implement the PeekerView interface and implement only the getPeeker method:
class Foo implements PeekerView<T>{
private Peeker<T> peeker = new PeekerImpl();
public Peeker<T> getPeeker() {
return peeker;
}
}
To implement the Pattern you basically just move all delegate calls to the PeekerView interface's default methods.
By the way I think "virtual field pattern", as Brian Goetz calls it, is not the best name for this. I guess it makes sense if you only look at the interfaces - the getter acts like a virtual field in this case. If you look at the whole thing though, including the implementing class, it is effectively like some kind of mixin (as it is also called in the other linked article). I would call it Mixin Pattern instead, because I've seen it referred to by that name more often.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have two similar classes. I would like to merge it into one. Objects of these classes are used in many different places. Is it possible to do it safely in Eclipse?
If you have two classes that are similar in some ways (but possibly not in others), you could create an Interface that describes the methods that are common to both of them. Then, you would have your two classes implement that Interface. Elsewhere in your application, you could reference the Interface as the formal parameters to your methods. Here's an example (see code below).
There is no automatic way to do this in an IDE-- you've got to take the time to design your object hierarchy (the relationships between your classes, and the API that your application will use to interact with them) manually.
public Interface Automobile{
//define an interface that describes the methods common to your two classes
public void drive();
}
//this is one of your two classes
public class Sedan implements Automobile{
public void drive(){
//Sedan-specific implementation here
}
}
//here's the other one. It's similar in that it has a drive method, but different
//in that it's implementation for drive() is different, and there might be
//other stuff in this class that is different from Sedan. However, it still is-an
//Automoblie
public class RaceCar implements Automobile{
public void drive(){
//RaceCar-specific implementation here
}
}
public class YourApplication{
//some method that accepts either one of the two classes you
//described as being "similar"
public void someMethod(Automobile automobile){
//you could pass in either a Sedan or a RaceCar, and
//the corresponding drive() method would get called
automobile.drive();
}
public static void main(String args[]){
Automobile car1 = new Sedan();
Automobile car2 = new RaceCar();
someMethod(car1);
//call the same method, but with car2!
someMethod(car2);
}
}
Eclipse can't do that automatically, You will have to go to one class, press control+a then control+c then go to the other class and press control+v.
Use Refactor->Extract Interface for each class to create two new interfaces and change the sources to use them instead of the classes.
Now create a new class implementing both these interfaces and remove the old classes. This should only cause your factory methods for the interfaces to break.
Change your factory methods to return this new class and leave all the interface usages in place.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
J. Bloch in his Effective Java written for Java 6 mentioned the following (Item 17):
If you feel that you must allow inheritance from such a class, one
reasonable approach is to ensure that the class never invokes any of
its overridable methods and to document this fact. In other words,
eliminate the class’s self-use of overridable methods entirely.
Item 18:
If you use abstract classes to define types, you leave the programmer
who wants to add functionality with no alternative but to use
inheritance. The resulting classes are less powerful and more fragile
than wrapper classes.
While interfaces are not permitted to contain method implementations,
using interfaces to define types does not prevent you from providing
implementation assistance to programmers.
Now in Java 8 with its default method's implementation (using the other methods in the interface) interfaces are dangerous for inheritance.
For instance:
public inteface MyInterface{
public void compute(Object o);
public default void computeAll(List<Object> oo){
for(Object o: oo)
compute(o); //self-use
}
}
So, according to J. Bloch, it may introduce some problems when we try to implement the interface, because:
Overriding the methods like this (similar to what J.Bloch provided):
public class MyInterfaceCounter implements MyInterface{
private int count = 0;
#Override
public void compute(Object o) {
count++;
}
#Override
public void computeAll(List<Object> oo){
count += oo.size(); //Damn!!
MyInterface.super.computeAll(oo);
}
}
The client access the interfaces's internals, i.e. they have to know about the default implementation.
What to do with it in Java 8? Are the rules from Effective Java apply still applicable?
Moreover, we can't declare the default method as final (as we can do for classes, it would make the self-use not too dangerous for overriders).
Okay, take the answer from your previous question and look what we can apply here:
You could simply avoid self-use.
In this case you can't. While implementing that interface your only choice to rely on (if you want to give a default implementation) is the method compute. You have to use it or not give an implementation at all.
You could make one of the methods involved final, so it can't be overridden.
That won't work in an interface as well.
You could make the class final, so it can't be extended.
That won't work in an interface.
You could describe the class's self-use patterns in its Javadoc comment (meeting the requirement of letting other people know).
That is the only choice left here. Either document it or don't give a default implementation.
So yes, the basic idea of it still applies, however your choices are somewhat limited.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I've been trying to learn Java and trying to really understand it and how it works. I was able to understood what an interface was (or so I think). I've also seen some examples with them... BUT I haven't been able to understand how some interfaces have methods that you implement, and they already come with some kind of functionality... aren't you supposed to write that functionality every time you implement that method?
To give some kind of example, there's LibGDX, a very well-known library for game developing in Java. Your application class has to implement a interface that has methods like "render()". When you write your application you put all the stuff related to rendering in the "render()" method... but how does it knows what to do with that, if it's just an interface which only defines the name and return type of render()?
Sorry for my english, and thank you.
EDIT: Thanks for your answers, yes I am kind of new in this... so well I get confused, you've been really helpful!.
Interfaces
Think of an interface as a collection of abstract methods. So this special class may be implemented inside my other classes. So that it inherits it's methods.
Think of it as a child class signing a contract with this parent class and promising that it will follow the same behavior as the interface. OTHERWISE, it'll have to declare itself as an abstract class(That's a whole other question to tackle).
In Java we are not allowed to extend multiple classes(as opposed to C#) in order to keep things simple. We are however, allowed to implement as many interfaces as we need.
To give you an example, what do Apples, Oranges, Blueberries have in common? They are all fruit, thus to 'force' them to have the same characteristics I create a Fruit interface, like so:
interface Fruit {
public void name();
public void colour();
}
And then implement them in my Apple class:
public class Apple implements Fruit{
public void name(){
System.out.println("Apple");
}
public void colour(){
System.out.println("Red");
}
}
So that Apple.java is forced to use the name() and colour() method and thus we will never come across an Apple object which doesn't have both name and colour!
Hope to have cleared it up
Also, I do recommend checking - Tutorials Point
As they post rather clear tutorials. For future reference, I highly recommend you search on StackOverflow for answers prior to posting your question as it will lead to alot of negative votes!
Interfaces can definitely be challenging concept to understand. Sometimes you need to know in advance that some method will exist on a given type. LIke in your case the LibGDX has a render method. The LibGDX at some point needs to call a render method but LibGDX doesn't know how that method is implemented, it just knows that it needs to call render. So, they say please implement this interface and tell us how to render. Then when we get around to calling the render() we will make sure that it gets called at the right time and invokes your code.
Perhaps this could be said another way. Sometimes when you use other software they do lots of work for you. At some point though you have to find a way to hook into the service that they provide. By implementing that interface you provide an implementation for the render() and they are nice enough to call it for you at the right time so that the rendering can take place.
Interfaces allow for polymorphism. Essentially, the LibGDX can call the render() on anything that implements their interface. Because you have implemented their interface their code know knows that a render() must exist on the class. The reason that this is polymorphic is because many different codebases will implement the interface and provide their own custom implementation of render and again LibGDX will happily invoke their method and run their implementation of that method.
Hope that helps!
Using your example, when your class implements an interface, the framework knows an instance of your class has a render() method, so the framework can call it when it needs to.
The framework doesn't need to know (or care) what class the instance is, and especially what super classes it may be inherited from. Nor does it care what the method does.
Further, referring to objects in the most abstract way is best practice, and in java an interface is the most abstract type (because it puts no restriction on class hierarchy) - see
Liskov substitution principle for more on this concept.
This arrangement gives great flexibility to how you may implement your code.
It doesn't. An interface is simply a contract. To Java, this means that if a concrete Object exists which implements that interface, it will have implementations of the methods defined in the contract.
A simple example should help demonstrate:
ExampleInterface.java
public interface ExampleInterface {
int operation(int a, int b);
}
ExampleAddition.java - implements the interface using addition as the operation.
public class ExampleAddition implements ExampleInterface {
#Override
public int operation(int a, int b) {
return a+b;
}
}
ExampleSubtraction.java - implements the interface using subtraction as the operation.
public class ExampleSubtraction implements ExampleInterface {
#Override
public int operation(int a, int b) {
return a-b;
}
}
ExampleMain.java - Contains anonymous inner class which uses multiplication as the operation.
public class ExampleMain {
public static void main(String[] args) {
ExampleInterface first = new ExampleAddition();
ExampleInterface second = new ExampleSubtraction();
ExampleInterface third = new ExampleInterface() {
#Override
public int operation(int a, int b) {
return a*b;
}
};
System.out.println(first.operation(10,5));
System.out.println(second.operation(10,5));
System.out.println(third.operation(10,5));
}
}
So what's the point of all this? Well the point is that all interface implementations are interchangeable, and you can use whichever you fancy. Now clearly in this example it's not particularly useful. It's more useful if you have for instance a data access object, and you want to use different technologies to access your data layer. You might want to have a hibernate implementation in production, and plain old JDBC implementation for local development, and a Mockito version for testing. This can all be done, because they share a common interface, they are effectively drop-in replacements for each other. In libGDX however I suspect there will only ever be one implementation, but it still must comply to the same contract. This let's them write a game loop that works independently of your concrete implementation.