This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why no static methods in Interfaces, but static fields and inner classes OK?
I want to know that why interface do not allow static block, but they allow to declare static variable.
What if i want to intialize a static variable on some logic.
edit: Earlier i did not post my query in better form but this is my query with sample code. please look into it.
interface A {
static class XYZ {
public static void methodA() {
// some implementation
System.out.println("methodA");
}
public static void methodB() {
// some more implementation
System.out.println("methodB");
}
}
void methodC();
}
public class ABC implements A {
public static void main(String[] args) {
A.XYZ.methodA();
}
#Override
public void methodC() {
// TODO Auto-generated method stub
}
}
Since purpose of interface is to provide a mechanism where users/implementors of the interface can implement the properties( methods) according to their needs.
But if i am allowed to add implementation in interface then some how that purpose of interface is defeated, please make me clear why this implementation in the interface is permitted, there must be something that is why and what is that fact, that is what i want to know
They designed interfaces to not allow implementations; a static block would constitute an implementation, so it is not allowed.
Related
This question already has answers here:
Java - Alternatives to forcing subclass to have a static method
(5 answers)
Is there a way to make sure classes implementing an Interface implement static methods?
(9 answers)
Closed 5 years ago.
I want each class that implements an interface to have a static factory method, as defined by the interface. I.e:
public interface Handle {
public static Handle GetHandle() {
return null;
}
public void DoThings();
}
public class HandleA implements Handle {
private HandleA();
public static HandleA GetHandle() {
return new HandleA();
}
public void DoThings() {
return;
}
}
// This is allowed even though HandleB doesn't provide a GetHandle()
public class HandleB implements Handle {
private HandleB();
public void DoThings() {
return;
}
}
Reading past questions, it seems like the static method GetHandle() isn't enforced in concrete classes of Handle because that's not what the intended design behavior of static interface method is. Is there another way to do what I want? (i.e enforce all implementations of Handle to provide a "factory" GetHandle() method).
You cant enforce a class to have a static method in Java.
This question already has answers here:
What is the difference between static and default methods in a Java interface?
(12 answers)
Closed 5 years ago.
interface TestInterface
{
public static void square(int a)
{
System.out.println("Square is "+a*a);
}
public static void show()
{
System.out.println("Default Method Executed");
}
}
class TestClass implements TestInterface
{
public void square(int a)
{
System.out.println(a*a);
}
public void show()
{
System.out.println("Overridden Method");
}
public static void main(String args[])
{
TestClass d=new TestClass();
d.square(4);
TestInterface.square(4);
TestInterface.show();
d.show();
}
}
I have a doubt in my code. I learnt that static methods cannot be overridden in JAVA, but it seems to be working fine here.
When i give both default and static keywords together, like this
interface TestInterface
{
default static void square(int a)
{
System.out.println("Square is "+a*a);
}
public static void show()
{
System.out.println("Default Method Executed");
}
}
An error crops up as follows:
illegal combination of modifiers: static and default
What is the reason for JAVA treating this as an error?
A static method is meant to be called without an instance of the class/interface concerned. Usually they are meant to be utility methods.
A default method is meant to be called on an instance of the interface concerned. All implementations of this interface will have this method definition, unless it is overridden.
The reason these two terms are not allowed together is simply because they contradict each other: default requires an object, static requires no object.
TestClass.show() and TestClass.square() are not static and therefore do not override the static methods in the interface. They are member methods and require an object to call them. On the other hand, the methods with the same name in the interface are static and so you can call them with the interface name or class name without an object.
This question already has answers here:
What is the "default" implementation of method defined in an Interface?
(3 answers)
Closed 4 years ago.
A java interface say "TestInterface" having 2 methods method1(), method2() is implemented by 100 different classes. Now I need to introduce a new method in TestInterface without making changes to other classes which already implemented it. How do I achieve it in java?
In my experience, the best way to do this is often to extend your Interface
public interface TestInterfaceEx extends TestInterface
Then, you can add methods to TestInterfaceEx, have the classes you want implement that, and use
if (myinstance instanceof TestInterfaceEx) {
myinstanceEx = (TestInterfaceEx) myinstance;
//...
}
in places where you want to use this new functionality
now from java 8 you can add default method in your interface, that method(default method in the interface) is present in all the classes that will implement it....
Ex :--
public class Java8Tester {
public static void main(String args[]) {
Vehicle vehicle = new Car();
vehicle.print();
}
}
interface Vehicle {
default void print() {
System.out.println("I am a vehicle!");
}
static void blowHorn() {
System.out.println("Blowing horn!!!");
}
}
interface FourWheeler {
default void print() {
System.out.println("I am a four wheeler!");
}
}
class Car implements Vehicle, FourWheeler {
public void print() {
Vehicle.super.print();
FourWheeler.super.print();
Vehicle.blowHorn();
System.out.println("I am a car!");
}
}
From Java8:
For example, if several classes such as A, B, C and D implement an interface XYZInterface then if we add a new method to the XYZInterface, we have to change the code in all the classes(A, B, C and D) that implement this interface. In this example we have only four classes that implement the interface which we want to change but imagine if there are hundreds of classes implementing an interface then it would be almost impossible to change the code in all those classes. This is why in java 8, we have a new concept “default methods”. These methods can be added to any existing interface and we do not need to implement these methods in the implementation classes mandatorily, thus we can add these default methods to existing interfaces without breaking the code.
We can say that concept of default method is introduced in java 8 to add the new methods in the existing interfaces in such a way so that they are backward compatible. Backward compatibility is adding new features without breaking the old code.
The method newMethod() in MyInterface is a default method, which means we need not to implement this method in the implementation class Example. This way we can add the default methods to existing interfaces without bothering about the classes that implements these interfaces.
interface MyInterface{
/* This is a default method so we need not
* to implement this method in the implementation
* classes
*/
default void newMethod(){
System.out.println("Newly added default method");
}
/* Already existing public and abstract method
* We must need to implement this method in
* implementation classes.
*/
void existingMethod(String str);
}
public class Example implements MyInterface{
// implementing abstract method
public void existingMethod(String str){
System.out.println("String is: "+str);
}
public static void main(String[] args) {
Example obj = new Example();
//calling the default method of interface
obj.newMethod();
//calling the abstract method of interface
obj.existingMethod("Java 8 is easy to learn");
}
}
This question already has answers here:
Explicitly calling a default method in Java
(6 answers)
Closed 8 years ago.
In java 8 I have something like this:
package test;
public class SimpleFuncInterfaceTest {
public static void carryOutWork(AFunctionalInterface sfi){
sfi.doWork();
}
public static void main(String[] args) {
carryOutWork(() -> System.out.println("Do work in lambda exp impl..."));
AImplementor implementsA = new AImplementor();
//carryOutWork(() -> implementsA.doWork());
BImplementor implementsB = new BImplementor();
carryOutWork(() -> implementsB.doWork());
}
}
#FunctionalInterface
interface AFunctionalInterface {
public void doWork();
default public void doSomeWork(){
System.out.println("FOO");
}
}
#FunctionalInterface
interface BFunctionalInterface extends AFunctionalInterface {
#Override
default public void doSomeWork(){
System.out.println("BAR");//Unreachable in same object?
}
}
class AImplementor implements AFunctionalInterface {
#Override
public void doWork() {
doSomeWork();
}
}
class BImplementor extends AImplementor implements BFunctionalInterface {
public void doSomeWork(){
super.doSomeWork();
new BFunctionalInterface(){
#Override
public void doWork() {
}}.doSomeWork();
System.out.println("WUK WUK");
}
#Override
public void doWork() {
doSomeWork();
}
}
Is there a way to call the default functional interface behavior from implementsB without having to create an anonymous inner class and invoking that?
That has a side effect (calling implementsA's method 2 times), what is desired is a call to the parent's implementation, and then have the childs implementation be able to call the child's default implementation, along with some specialization if needed. As you can see calling the parent's implementation is dead easy, but I don't see a way to avoid re-writing the default implementation unless I add a layer of indirection to the class that implements the child interface, and no way to enforce that.
For instance if A unlocked or provided access to a resource say a database, and B unlocks a second resource (another database), I see no way to make code unlock A and then B enforcing this contract through the use of Functional Interfaces, requiring that A and B be called. One level deep you can do it, but N levels deep looks like it's not possible.
I intended to use lambdas to avoid making expensive calls but to enforce a semantic order of operations on users of my library.
This question is not quite the same as "Explicitly calling a default method in Java", as this question is about interfaces N levels deep, not just calling a parent interfaces default method.
You can invoke an inherited interface default method using InterfaceName.super. The rules are the same as for other super method invocations: You can invoke the inherited method that you have overridden, but you can’t directly invoke the method which the inherited method might have overridden. E.g.
interface A
{
void foo();
default void toOverride() {
System.out.println("A");
}
}
interface B extends A
{
default void toOverride() {
A.super.toOverride();
System.out.println("B");
}
}
interface C extends B
{
default void toOverride() {
A.super.toOverride();// does not work
B.super.toOverride();
System.out.println("B");
}
}
class D implements B
{
public void toOverride() {
}
public void foo() {
D.this.toOverride();
B.super.toOverride();
A.super.toOverride(); // does not work!
}
}
But if each overriding method invokes its super method you have a chain of invocations. However, keep in mind that we are talking about interfaces. An implementation can always override a default method without invoking super at all.
More than a few times I've found my self working with a class that is closed (I can't modify it) that I wish implemented a nice narrow interface particular to my needs. My client code is supposed to own the interface but I know of no mechanism to announce that this closed class is a implementation of my narrowed interface.
I'm trying to allow this class to be passed in (dependency injected) to my code (composition) but also anything else that can support the narrowed interface. In other languages duck typing makes this trivial. I'm in java though, so I'm expecting to have to write a whole other class just to wrap the closed class to make this happen. Is there a way I'm missing?
Thanks
EDIT to address dupe:
The Interface Segregation Principle offers no mention of the closed class issue which is the point of this question. Please reconsider marking as dupe of this particular question.
This question:
Interface Segregation Principle- Program to an interface, has a good example of the interface segregation principle:
class A {
method1()
method2()
// more methods
method10()
}
class B {
A a = new A()
}
will become
interface C {
method1()
method2()
}
class A implements C{
method1()
method2()
// more methods
method10()
}
class B {
C c = new A()
}
But note how it requires a change to class A. If A is closed to modification how do I accomplish the same thing cleanly?
Depending on the situation, one possibility is to wrap all classes in a wrapper class that exposes the said interface, I mean something like this:
public class UnmodifyableObject {
public void method1();
public void method2();
public void method3();
public void method4();
}
Then you want the interface to look like:
public interface MyInterface {
public void method1();
public void method2();
}
As a solution you can wrap your UnmodifyableObject in a WrappedUnmodifyableObject:
public class WrappedUnmodifyableObject implements MyInterface {
private final UnmodifyableObject unmodifyableObject;
public WrappedUnmodifyableObject(final UnmodifyableObject unmodifyableObject) {
this.unmodifyableObject = Objects.requireNonNull(unmodifyableObject, "unmodifyableObject");
}
#Override
public void method1() {
unmodifyableObject.method1();
}
#Override
public void method2() {
unmodifyableObject.method2();
}
public void method3() {
unmodifyableObject.method3();
}
public void method4() {
unmodifyableObject.method4();
}
}
It does nothing more than delegate all methods, and of course it implements the interface.
A few important things to note are that:
- You should use composition over inheritance, it might look easier to just extend the class, but you do not control that code, it may remove methods or it may even be final.
- This does mean you have to do quite some work.
- If you do not want to do the work yourself, you might need to look into tools to change the bytecode either before execution or before loading the class.
Usage of this object would be via:
UnmodifyableObject unmodifyableObject = someExternalMethodCall();
MyInterface myInterfaceObject = new WrappedUnmodifyableObject(unmodifyableObject);
Use one or more adapters. Adapters are a type of wrapper that changes the interface of the wrapped class without the need to change its source.
class A {
method1()
method2()
// more methods
method10()
}
interface SegregatedI1 {
method1();
}
interface SegregatedI2 {
method2();
method3();
}
class ASegregatedI1Adapter implements SegregatedI1 {
private final A a;
AI1Adapter(A a){
this.a = a;
}
public void method1(){
a.method1();
}
}
Note that A could be an interface or a final class. Also note that an adapter could implement more than one of the segregated interfaces, or you can have separate adapters for each (I'd prefer the latter to keep inline with single responsibility).
Mark Peters suggested simply extending the closed class to avoid the wrapper. Since he hasn't posted an answer based on it I'll write one up.
I normally avoid inheritance in favor of composition as a knee jerk reaction but in this case it really seems to have merit. The main reason being writing a wrapper simply ends up moving the sin of coding to an implementation from the client method into the wrapper. Thus the only thing gained is a level of indirection. If that's all we get and we can find an easier way to get it why not?
Here's some code that slaps a very narrow roleinterface on a very popular and very closed library class: ArrayList.
public class MainClass {
public static void main(String[] args) {
OpenArrayList<String> ls = new OpenArrayList<String>();
ShowClient client = new ShowClient(ls);
ls.add("test1");
client.show();
ls.add("test2");
client.show();
}
}
//Open version of ArrayList that can implement roleinterfaces for our clients
public class OpenArrayList<E> extends ArrayList<E> implements ShowState {
private static final long serialVersionUID = 1L;
}
//Roleinterface for ShowClient
public interface ShowState {
public int size();
public String toString();
}
//Show method programmed to a roleinterface narrowed specifically for it
public class ShowClient {
private ShowState ss;
ShowClient(ShowState ss) {
this.ss = ss;
}
void show() {
System.out.println( ss.size() );
System.out.println( ss.toString() );
}
}
So, if you're going to do Interface Segregation when using a class closed to modification is there a reason not to do it this way?