Suppose I have an interface
interface MyInterface {
void doSomething();
void doSomethingElse();
/* way more methods */
}
and maybe a default implementation like this:
class StubbedMyInterface implements MyInterace {
void doSomething() {
throw new UnsupportedOperationException();
}
void doSomethingElse() {
throw new UnsupportedOperationException();
}
/* all the other methods */
}
The stubbed class simply exists so that implementers of the interface don't need to implement all the methods they do not care about.
Should the class StubbedMyInterface be declared abstract? Or should it have a protected default constructor (so that e.g. a unit test for StubbedMyInterface which checks that all methods throw the desired exception can instantiate the class without creating a needless subclass)? Or should the class just be a normal public class?
UPDATE:
OK, I see I should provide more context. This problem occured while implementing a visitor pattern for an Abstract Syntax Tree. The interface defines one method per node type in the tree and these are quite a lot of types.
I have several of these Stub implementation:
One like the one above which is useful e.g. when processing the children of a certain node - in this case I know that only node type A,B and C can possibly be a child of the node whose children I process. And if I got this wrong I want some error message to point me to the problem.
One which just has empty implementations for each method - which is useful if I want to process only nodes I know what to do with and ignore the others.
One which by default traverses the children of each node which is useful if I want to traverse a full tree but care only about certain node types.
To me, this comes down to Booch. "A class should be minimalistic and complete." Is this class complete? If not, it should be abstract.
The nature of the structure isn't compelling. Is this class, on it's own, useful for something is the key factor. If not, it should be abstract.
If some of the interface method definitions are not supposed to be implemented, then I would prefer spreading them accross several interfaces.
Then I would implement only the exact interface, which holds the method definitions I'm interested in.
For example:
interface MyFirstInterface {
void doSomething();
}
interface MySecondInterface {
void doSomethingElse();
}
public class MyClass implement MySecondInterface {
void doSomethingElse() {
}
}
With Java 8, you can define a default implementation in the interface itself, which gives much more flexibility than an abstract class (you can inherit multiple interfaces) - so it could look like:
interface MyInterface {
default void doSomething() {
throw new UnsupportedOperationException();
}
default void doSomethingElse() {
throw new UnsupportedOperationException();
}
/* all the other methods */
}
With Java 7 and earlier, using an abstract class would make sense to provide a default basic implementation.
If implementers of the interface don't need to implement all the methods, they don't need implement this interface, they need only one interface in the hierarchy with needed method set.
I would use inheritance like this
interface MyFirstInterface {
void doSomething();
}
interface MySecondInterface extends MyFirstInterface {
void doSomethingElse();
}
Related
Is abstraction possible without inheritance? This is my code
abstract class whatever
{
abstract void disp1();
abstract void disp2();
abstract void disp3();
}
class what {
void disp1()
{
System.out.println("This is disp1");
}
}
public class threeClasses {
public static void main (String args[])
{
what obj =new what();
obj.disp1();
}
}
Please note above, how i:
did not extend the class "what" from abstract class "whatever" and yet the code runs perfectly with no errors
Did not declare class "what" as abstract (since it's not declaring the other two methods disp2() and disp3())
I am very confused. Please help.
You aren't using whatever (and Java naming conventions should be respected). The idea behind an abstract class (and inheritance) is that there is an interface contract. Let's examine it with a more practical example,
abstract class Whatever {
abstract void disp1();
void disp2() {
System.out.println("disp2");
}
void disp3() {
System.out.println("disp3");
}
}
Then make What extend it. Override two methods for demonstration (the annotation is a useful compile time safety check)
class What extends Whatever {
#Override
void disp1() {
System.out.println("This is disp1");
}
#Override
void disp2() {
System.out.println("This is disp2");
}
}
Finally, invoke methods on a What instance through the Whatever contract
public static void main(String args[]) {
Whatever obj = new What();
obj.disp1();
obj.disp2();
obj.disp3();
}
Which outputs
This is disp1
This is disp2
disp3
Note that What is providing the implementation for disp1 and disp2 while Whatever provides disp3.
There is no relationship between your abstract class and your concrete class. Whatever your definition of "abstraction", it actually represents a relationship between types. The abstract keyword does not establish that relationship between classes, it represents that relationship, and not by itself. The relationship needs to be extended from both sides.
abstract is a declaration from one side about a promise that must be kept, for an inheriting type either to implement abstract methods or to ask for that promise from its inheriting types.
The other side makes the promise by being a class that inherits from the abstract type. Without inheritance, the concrete type loses the is-a connection.
You will get the compiler error you're complaining about missing if you correct one major mistake you made. You failed to use the #Override annotation. Always use the #Override annotation when you intend to override a method, or you will forever enjoy just the sort of bug you show here.
I think what he meant was if we can implement abstract class's method without inheriting abstract class.
You might be thinking if we can do it with composition/association/aggregation relation.
To that, I will answer: NO because you can't create an object of abstract class as in these relations you have to make object or reference of the object.
So, the only way to implement abstract methods is through inheritance.
This is a logical development of another question I asked.
Supposedly you have an interface, some methods of which might either be supported by a concrete implementation or not. The goal is to provide a reasonable way for the client to find out whether his particular implementation supports each particular method and to recover if it doesn't.
The solution I came up with utilizes the standard java.lang.UnsupportedOperationException, which is thrown by the concrete implementation if the method is unsupported:
public interface CommonInterface {
void possiblyUnsupportedOperation () throws java.lang.UnsupportedOperationException;
}
However, this is claimed to be a bad solution, since the exception mechanism should not be used as a means of checking whether an operation is available. So the alternative suggestion is to use tester methods:
public interface CommonInterface {
void possiblyUnsupportedOperation ();
boolean isOperationSupported ();
}
But what if the interface has a whole multitude of optional operations? Should I use multiple tester functions? Should I create a separate Enum to map the optional methods onto and pass it as a method descriptor to a single tester function? Both variants look kinda clunky to me.
Is there an alternative way that is both an elegant code and a good design solution?
If you own that interface you could extract a Parent interface with the methods that are always going to be implemented and inherit from that interface.
public interface ParentCommonInterface {
void method1();
void method2();
}
public interface CommonInterface extends ParentCommonInterface {
void possiblyUnsupportedOperation();
}
class MyClass implements ParentCommonInterface {...}
If you don't own that interface you can create an Adapter class and use that one to declare the object.
public interface CommonInterface {
void possiblyUnsupportedOperation();
boolean isOperationSupported();
}
public class AdapterClassOne implements CommonInterface {
void possiblyUnsupportedOperation() {...}
boolean isOperationSupported() {return false;}
}
}
I have 3 classes.
public interface Operation {
void move();
void delete();
void search(String criteria);
}
public abstract class AbstractOperationProcessor implements Operation {
public void move() {
// some logic
}
}
public class DailyMailProcessor extends AbstractOperationProcessor{
// need to hide this method because I don't want to provide them to customer
public void delete() {}
public void search(String criteria) {}
}
What I need is to hide methods delete() and search(String) from API. How can I do it without changing interface Operation and abstract class AbstractOperationProcessor?
You cannot. The best you can do is implement stubs that throw something like NotImplementedException and document this fact.
I would use this as an opportunity to examine the definition of the top-level interface. If you need to hide some of its methods then the real problem may be that it aggregates unrelated functionality. You may need to split it into two separate interfaces.
Remember, you can "inherit" (i.e. implement) multiple interfaces.
As the other answers already stated: You cannot hide a method of a superclass. There is also a good reason that you cannot do this: Polymorphism allows you to pass any object of a subtype where an object of a supertype is needed. In your case, if you have a method
void foo(Operation op){op.delete()}
you can call
foo(new DailyMailProcessor())
As you can see, foo does not know the exact type of op, but because delete is in Operation's interface, the method delete can be called.
If you happen to want to remove some methods from a subtype's interface, you are probably not implementing a behavioral subtype! I suggest you have a look at the Liskov Principle, which is one of the fundamental principles in object oriented programming.
If, what you have is not a behavioral subtype, you are wrongly trying to achieve code reuse by inheritance. You should use composition instead. Favor composition over inheritance (Item 16, Effective Java). The reason to favor composition in your case is obvious: You do not have to throw an UnsupportedOperationException (as mentioned in the other answers) and hereby gain static safety.
Edit: To clarify what I mean when telling you to use composition: Instead of having class DailyMailProcessor extending Operation, give it an member variable of type Operation and forward calls to the methods you want to support to the member variable.
public interface Operation {
void move();
void delete();
void search(String criteria);
}
public class DailyMailProcessor {
private Operation op;
public DailyMailProcessor {/*instantiate op*/}
void move() {op.move();}
}
You cannot do that. Every method declared in the interface should be implemented by the class. What you can do is you just implement those methods but do not give any definition to it.
Edit:
As suggested in the comments, UnsupportedOperationException might be a better choice.
Original answer:
There is the IllegalStateException just for that. Just make all the methods you don't want to implement throw that. Just do:
public class DailyMailProcessor extends AbstractOperationProcessor {
public void delete() {
throw new IllegalStateException();
}
public void search(String criteria) {
// do something useful here
}
}
the best solution that handle your probleme, if, and only if you want to have it in an elegante way, is to use a component system and it would look some this like that:
abstract class Component {
abstract void perform();
}
abstract class Move extends Component {
void perform() { ... }
}
class AbstractOperationProcessor {
List<Component> components;
...
}
In the Collection Interface I found a method named removeIf() that contains its implementation.
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
I want to know if there is any way to define method body in an interface?
What is the default keyword and how does it work?
From https://dzone.com/articles/interface-default-methods-java
Java 8 introduces “Default Method” or (Defender methods) new feature, which allows developer to add new methods to the interfaces without breaking the existing implementation of these interface. It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method.
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public class ClassAB implements A {
}
There is one common question that people ask about default methods when they hear about the new feature for the first time:
What if the class implements two interfaces and both those interfaces define a default method with the same signature?
Example to illustrate this situation:
public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public interface B {
default void foo(){
System.out.println("Calling B.foo()");
}
}
public class ClassAB implements A, B {
}
This code fails to compile with the following result:
java: class Clazz inherits unrelated defaults for foo() from types A and B
To fix that, in Clazz, we have to resolve it manually by overriding the conflicting method:
public class Clazz implements A, B {
public void foo(){}
}
But what if we would like to call the default implementation of method foo() from interface A instead of implementing our own.
It is possible to refer to A#foo() as follows:
public class Clazz implements A, B {
public void foo(){
A.super.foo();
}
}
Those methods are called default methods. Default method or Defender method is one of the newly added features in Java 8.
They will be used to allow an interface method to provide an implementation used as default in the event that a concrete class doesn't provide an implementation for that method.
So, if you have an interface, with a default method:
public interface Hello {
default void sayHello() {
System.out.println("Hello");
}
}
The following class is perfectly valid:
public class HelloImpl implements Hello {
}
If you create an instance of HelloImpl:
Hello hello = new HelloImpl();
hello.sayHello(); // This will invoke the default method in interface
Useful Links:
Updated Oracle Tutorial
Everything about Java 8
Defender Methods
I did a bit of research and i found the following. Hope this helps.
Existing problem
Normal interface methods are declared as abstract and must be defined in the class that implements the interface. This 'burdens' the class implementer with the responsibility to implement every declared method. More importantly, this also means that extending an interface is not possible after 'publication'. Otherwise, all implementers would have to adapt their implementation, breaking backwards source and binary compatibility.
Solution adopted in Java 8
To cope with these problems, one of the new features of JDK 8 is the possibility to extend existing interfaces with default methods. Default methods are not only declared, but also defined in the interface.
Important points to note
Implementers can choose not to implement default methods in
implementing class.
Implementers can still override default
methods, like regular non-final class methods can be overridden in
subclasses.
Abstract classes can even (re)declare default methods
as abstract, forcing subclasses to reimplement the method (sometimes
called 're-abstraction').
i have an abstract class BaseClass with a public insert() method:
public abstract class BaseClass {
public void insert(Object object) {
// Do something
}
}
which is extended by many other classes. For some of those classes, however, the insert() method must have additional parameters, so that they instead of overriding it I overload the method of the base class with the parameters required, for example:
public class SampleClass extends BaseClass {
public void insert(Object object, Long param){
// Do Something
}
}
Now, if i instantiate the SampleClass class, i have two insert() methods:
SampleClass sampleClass = new SampleClass();
sampleClass.insert(Object object);
sampleClass.insert(Object object, Long param);
what i'd like to do is to hide the insert() method defined in the base class, so that just the overload would be visible:
SampleClass sampleClass = new SampleClass();
sampleClass.insert(Object object, Long param);
Could this be done in OOP?
There is no way of hiding the method. You can do this:
#Override
public void insert(Object ob) {
throw new UnsupportedOperationException("not supported");
}
but that's it.
The base class creates a contract. All subclasses are bound by that contract. Think about it this way:
BaseObject b = new SomeObjectWithoutInsert();
b.insert(...);
How is that code meant to know that it doesn't have an insert(Object) method? It can't.
Your problem sounds like a design problem. Either the classes in question shouldn't be inheriting from the base class in question or that base class shouldn't have that method. Perhaps you can take insert() out of that class, move it to a subclass and have classes that need insert(Object) extend it and those that need insert(Object, Object) extend a different subclass of the base object.
I don't believe there's a clean way to completely hide an inherited method in Java.
In cases like this, if you absolutely can't support that method, I would probably mark that method as #Obsolete in the child class, and have it throw a NotImplementedException (or whatever the equivalent exception is in Java), to discourage people from using it.
In the end, if you inherit a method that does not make sense for your child class, it could be that you really shouldn't inherit from that base class at all. It could also be that the base class is poorly designed or encompasses too much behavior, but it might be worth considering your class hierarchy. Another route to look at might be composition, where your class has a private instance of what used to be the base class, and you can choose which methods to expose by wrapping them in your own methods. (Edit: if the base class is abstract, composition might not be an option...)
As Cletus points out, this is really a design problem, in that you are trying to create a child class that does not obey the contract of its parent class.
There are rare circumstances where working around this by e.g. throwing an exception might be desirable (or at least an acceptable compromise -- for example, the Java Collections Framework) but in general it's a sign of poor design.
You may wish to read up on the Liskov substitution principle: the idea that (as Wikipedia puts it) "if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program". By overriding a method to throw an exception, or hiding it any other way, you're violating this principle.
If the contract of the base class' method was "inserts the current object, or throws an exception" (see e.g. the JavaDoc for Collection.add()) then you could argue you're not violating LSP, but if that is unexpected by most callers you may want to rethink your design on these grounds.
This sounds like a badly designed hierarchy -
If no default exists and the user shouldn't call the method at all you can mark the method as #Deprecated and throw an UnsupportedOperationException as other posters have noted. However - this is really only a runtime check. #Deprecated only throws a compiler warning and most IDEs mark it in some way, but there's no compile time prevention of this. It also really sucks because it's possible to get the child class as a parent class reference and call the method on it with no warning that it's "bad" at all. In the example below, there won't be any indication until runtime that anything's wrong.
Example:
// Abstract base builder class
public abstract class BaseClassBuilder {
public final doBuild() {
BaseClass base = getBase();
for (Object obj : getObjects() {
base.insert(obj);
}
}
protected abstract BaseClass getBase();
protected abstract Object[] getObjects();
}
// implementation using SampleClass
public class SampleClassBuilder extends BaseClassBuilder {
#Override
protected BaseClass getBase() {
return new SampleClass();
}
#Override
protected Object[] getObjects() {
Object[] obj = new Object[12];
// ...
return obj;
}
}
However, if a sensible default exists, you could mark the inherited method as final and provide the default value inside of it. This handles both the bad hierarchy, and it prevents the "unforseen circumstances" of the above example.
Example:
public abstract class BaseClass {
public void insert(Object object) {
// ...
}
}
public class SampleClass extends BaseClass {
public static final Long DEFAULT_PARAM = 0L;
public final void insert(Object object) {
this.insert(object, DEFAULT_PARAM);
}
public void insert(Object object, Long param) {
// ...
}
}