Calling super class method inside implemented abstract method - java

Basicaly I have a need for several methods that do the same thing but with different parameters the sub-classes can chose from, and still force the implementation.
Is this a correct approach/design ?
EDIT: I have edited the addItem() body, these methods contain the final logic that is used to handle the passed parameters
public abstract Class A {
public abstract void addItemImpl()
addItem(String s) {
// do stuff
}
addItem(Collection c) {
// do stuff
}
addItem(Item item) {
// do stuff
}
}
public Class B extends A {
addItemImpl() {
addItem("text, text2")
}
}
public Class C extends A {
addItemImpl() {
addItem([item, item2])
}
}

No, this will not work.
You will not be able to define the "doStuff()" method because you have to handle the parameters. You provide not enough information to give you detailed help. But it's possible that generics might come in handy:
public abstract Class A<T> {
public addItem(T t) {
// dostuff with t
}
}
public Class B extends A<String> {
}
public Class C extends A<Collection> {
}

This is a perfect case for: Favor composition over inheritance.
Your subclasses don't fully benefit from the superclass and don't depend on its implementation details. Then define an interface for the contract B and C must obey (addItemImpl()) and compose them with A.
Ask yourself: is B really an A? is C really and A?

What you have is technically correct, but with out knowing what addItem actually does it is difficult to know if this is the best solution. My guess would be that there probably is a better way.
If addItem essentially set values to be used in the doStuff, I would just do that work in the Class B and C instead. Any others that need to do it the same way as B could extend it instead of A.
Edit: Based on your edit, I would say this is probably a bad example to use an abstract class. There is no truely shared functionality. An interface would be more appropriate as you need a different implementation for each. You are just trying to hide that inside an abstract class. I would change A to an interface along with using generics.
Only go the abstract class route if there is actually shared code that is exactly the same in all the classes without having to do any tricks to make it work (like above).

If you need force implementation for few methods, then Abstract methods are ideal.
But be careful only the very first Non-Abstract sub-class of the Super-class is bound to implement all the abstract methods in it....

Related

abstraction can be done without inheritance? java

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.

Implementation of Multiple Parallel interface

Suppose I have an interface defined as:
public interface TestInterface1 {
public void add();
}
which is implemented by classes A, B and C.
Now I need to add a subtract functionality only to class C; for that I have created a new interface TestInterface2 and implemented that to class C:
public interface TestInterface2 {
public void sub();
}
Class C looks like this:
public class C implements TestInterface1, TestInterface2 {
public void add() {
System.out.println("I am in add");
}
public void sub() {
System.out.println("I am in Sub");
}
}
Now the problem is instances of C has been use in hundreds of places like this:
TestInterface1 c = new C();
And only class C is getting the add method of TestInterface1.
Is there any way or pattern to implement both the interfaces in class C so that where ever the object of class C is created, it gets both the method from TestInterface1 and TestInterface2?
If you can change your interfaces then make TestInterface1 extend the other one, so object created using first interface can use its parent methods.
public interface TestInterface1 extends TestInterface2{
public void add();
}
Before we get into this, you have to consider why you're even using interfaces for this at all. An interface guarantees that all instances are using the same implementations. If you want a specific class to have a more specific implementation, then that sounds more like a method on the concrete class more than it does a new interface at all.
Regardless, we can discuss your options. One of them is cleaner and conveys clear intent; the other muddies things.
The first option - which conveys clearer intent - is to eschew the usage of the more restrictive interface and instead use TestInterface2 for every declaration that you want to use C.
This means you'd write TestInterface2 c = new C(); everywhere you wanted to use it. Yes, you'd be changing it in all of the places that you're using C, but given that you have to have a method specifically attached to instances of C, this option is clearest.
This would be the same approach if you just wrote the method in C. There's really no difference between the two and I personally would prefer if you wrote the method that only belonged to C in C.
The second option - which muddies things and also requires Java 8 - is to use a default method. This requires that you implement it in the interface at first...
public interface TestInterface {
default void sub() {
System.out.println("I am in sub!");
}
}
...but you can override it in your class later. This muddies things because any class that implements TestInterface has access to this default method, which is likely not what you want for your requirements.

Why its not necessary to have abstract classes to have abstract method [duplicate]

Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.

What's the point in having an abstract class with no abstract methods?

Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.

Conflicting methods on interface multiple inheritance

I have the following interfaces (in Java, but it's more of an OO question, not language-specific, I'm interested in answers for any language)
public interface A {
int foo();
}
and
public interface B {
char foo();
}
If I now want to make the following class:
public class C implements A,B{
public int foo() {
return 0;
}
public char foo() {
return 0;
}
}
This won't compile because the methods are conflicting. Is there any way to make this work, or something with the same meaning (of course without modifying A or B, that would be trivial)?
No, the return type cannot be a deciding factor in making a method signature unique because you do not need to assign the returned value to anything, the compiler wouldn't know what to do in that case.
Concrete example:
...
C object = new C();
object.foo();
...
Which foo did I just call? Can't tell.
To make this work you'll need to have either different method names or different parameter types in the interface methods.
EDIT: assuming you have no control over the interfaces A and B (library classes or similar) this is the solution I'd take if I wanted to implement them in the same class:
public class C {
private objectA = new AImpl();
private objectB = new BImpl();
// Work with the objects here
private class AImpl implements A {
public int foo() {
// ...
}
}
private class BImpl implements B {
public char foo() {
// ...
}
}
}
The common solution is to give each method a different name. Avoid generic names that have a high chance of naming collision with another interface.
This problem is present because in OOP, is considered the existence of more one method with the same name but with different parameters and not by return type.
The problem is not the interface, the problem is the class.
Overloading comes with parameters.
There are several solutions to this problem in use. I am working on the assumption that these are independent interfaces, that the intention is multiple interface (implementation of two unrelated interfaces on the same object) and that overloading has nothing to do with it.
The solutions I am aware of are:
1. Scoping. A reference to foo() can be qualified as A.foo() or B.foo() to determine which is required.
1. Namespaces. The interfaces are inherited inside a namespace constructed for the purpose, and all references to foo() must be preceded by a namespace, eg A::foo(), B::foo().
1. Aliasing. One or both of the foo() methods are explicitly renamed when inherited. Calls become something like A_foo() and B_foo().
Ada certainly had a mechanism like this, and I think some variants of Pascal did too. I can find more examples if it's important.

Categories