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;
...
}
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;}
}
}
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();
}
I am facing the following problem:
I defined an abstract class that contains the public generate, clone, etc. methods that must be implemented by the subclass. However I would like to ensure that when these public methods are called certain other methods are also executed within the abstract class.
An obvious solution would be to make a protected abstract method to be implemented and a public non-abstract method that calls the abstract one and all the other methods that I need.
For example:
abstract class Representation {
public void generate(int variable) {
myFunction();
generateAbstract(variable);
}
protected abstract void generateAbstract(int variable);
private void myFunction() {
//do something
}
}
My question is how to solve it a nicer way, or if this is the way to go how to name the function in a user-friendly way.
Thanks!
Your way of solving this issue is so standard that it even has a name: it is called Template Method Pattern. The idea is to provide a public method that executes the steps of your algorithm at high-level, and use overrides of protected abstract methods in subclasses to deal with lower-level steps of the algorithm. This is the correct way of addressing the problem.
I would do it as you are doing it. I would make the wrapper method either
final so I can't be blown away in a subclass, or
document the hell out of the methods, indicating that the abstract method MUST be called...
#dasblinkenlight's answer identifies the design pattern that addresses your problem: Template Method. I like this Template Method link more than the wikipedia entry that answer references. Also, I like answers with code examples:
// Demonstrate the template method design pattern
// straight out of GoF example
abstract class AbstractClass {
// Final ensures extender does not override, but depends on your design
final void templateMethod() {
primitiveOperation1();
primitiveOperation2();
}
// document extenders should keep as protected
// so clients do not call directly
protected abstract void primitiveOperation1();
protected abstract void primitiveOperation2();
}
public class ConcreteClass extends AbstractClass {
#Override
protected void primitiveOperation1() {
System.out.println("ConcreteClass.primitiveOperation1()");
}
#Override
protected void primitiveOperation2() {
System.out.println("ConcreteClass.primitiveOperation2()");
}
}
I think your suggested method is quite elegant enough. I've certainly solved the same problem in this way before. I'd possibly call your method doGenerate() (or something without the word Abstract in it).
I think the easiest way to do this would be to ensure that super.generate is called. Since Java doesn't have a good mechanism for informing a class of when it has been subclassed (others like Ruby do), there's not much you can do to force a subclass that implements an abstract method to call another method.
As pointed out before, what you suggested is the correct approach according to the Template method pattern. What is left is the naming issue. I would not call the function to be overwritten "generateAbstract" because when it is implemented it is not abstract anymore. I recommend something like "makeGenerate()" which reflects the original function and implies what it does.
abstract class Representation {
public void generate(int variable) {
myFunction();
makeGenerate(variable);
}
protected abstract void generateAbstract(int variable);
private void myFunction() {
//do something
}
}
public class ConcreteClass extends Representation {
#Override
protected void makeGenerate() {
...
}
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) {
// ...
}
}