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.
Related
For a project, I have following classes:
SuperClass
Subclass 1
Subclass 2
The two subclasses extend the superclass.
Now, I need a third class with the EXACT behaviour (read, same overriden method implementations) of both SubClass 1 and Subclass 2.
Because Subclass 1 overrides only 1 method in SuperClass, and Subclass 2 doesn't override that method, I want to make the third class inherit Superclass and just implement it with the methods of Subclass 1 and Subclass 2. Now, is this good OO-design? I see no other solution because multiple inheritance in Java just isn't possible. Are there any alternatives?
Java8 introduced default and static methods for interfaces. To a certain degree, that allows for multiple inheritance. But most likely, the correct solution would be to rework your design.
You see, inheritance is not about code re-use. It is about creating useful abstractions; and make good use of polymorphism for example.
In your case: maybe those functionalities could/should be put into smaller interfaces; and then segregated into their own, independent classes. And then you use composition of objects instead of inheritance to build the thing you need.
Here is an example using Java 8's default methods as #GhostCat mentioned. I don't see anything wrong with this OO design per se. Whether or not it's appropriate to your use case depends on the details of the problem you're solving.
public class Main {
public static void main(String... args) {
SuperClass sc = new SubClass3();
sc.foo(); // overridden foo
sc.bar(); // overridden bar
}
interface SuperClass {
default void foo() {
System.out.println("default foo");
}
default void bar() {
System.out.println("default bar");
}
}
interface SubClass1 extends SuperClass {
#Override
default void foo() {
System.out.println("overridden foo");
}
}
interface SubClass2 extends SuperClass {
#Override
default void bar() {
System.out.println("overridden bar");
}
}
static class SubClass3 implements SubClass1, SubClass2 {}
}
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.
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.
Is there any way to NOT implement all of the methods of an interface in an inheriting class?
The only way around this is to declare your class as abstract and leave it to a subclass to implement the missing methods. But ultimately, someone in the chain has to implement it to meet the interface contract. If you truly do not need a particular method, you can implement it and then either return or throw some variety of NotImplementedException, whichever is more appropriate in your case.
The Interface could also specify some methods as 'default' and provide the corresponding method implementation within the Interface definition (https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html). These 'default' methods need not be mentioned while implementing the Interface.
The point of an interface is to guarantee that an object will outwardly behave as the interface specifies that it will
If you don't implement all methods of your interface, than you destroy the entire purpose of an interface.
We can override all the interface methods in abstract parent class and in child class override those methods only which is required by that particular child class.
Interface
public interface MyInterface{
void method1();
void method2();
void method3();
}
Abstract Parent class
public abstract class Parent implements MyInterface{
#Override
public void method1(){
}
#Override
public void method2(){
}
#Override
public void method3(){
}
}
In your Child classes
public class Child1 extends Parent{
#Override
public void method1(){
}
}
public class Child2 extends Parent{
#Override
public void method2(){
}
}
I asked myself the same question, and then learned about Adapters. It solved my problem, maybe it can solve yours. This explains it very well : https://blogs.oracle.com/CoreJavaTechTips/entry/listeners_vs_adapters
You can do that in Java8. Java 8 introduces “Default Method” or (Defender methods) new feature, which allows a developer to add new methods to the Interfaces without breaking the existing implementation of these interfaces.
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.
interface OldInterface {
public void existingMethod();
default public void DefaultMethod() {
System.out.println("New default method" + " is added in interface");
}
}
//following class compiles successfully in JDK 8
public class ClassImpl implements OldInterface {
#Override
public void existingMethod() {
System.out.println("normal method");
}
public static void main(String[] args) {
ClassImpl obj = new ClassImpl ();
// print “New default method add in interface”
obj.DefaultMethod();
}
}
Define that class as an abstract class. However, you must implement those unimplemented methods when you want to create an instance of it (either by using a subclass or an anonymous class).
It is possible and it is easy. I coded an example.
All you have to do is inherit from a class that does implement the method. If you don't mind a class that is not instantiable, then you can also define an abstract class.
If you want an instantiable class, it is not possible. You may try to define an abstract class, though.
If you try to implement an interface and you find yourself in a situation where there is no need to implement all of them then, this is a code smell. It indicates a bad design and it violates Liskov substitution principle. Often this happens because of using fat interface.
Also sometimes this happens because you are trying to implement an interface from an external dependency. In this case, I always look inside the source code to see if there is any implementation of that interface which I can either use it directly or subclass it and override methods to my needs.
We can use Adapter classes ,which reduces complexcity by not making mandatory to implement all the methods present in the interface
Adapter class is a simple java class that implements an interface with only EMPTY implementation .
Instead of implementing interface if we extends Adapter class ,we provide implementation only for require method
ex--- instead of implementing Servlet(I) if we extends GenericServlet(AC) then we provide implementation for Service()method we are not require to provide implementation for remaining meyhod..
Generic class Acts as ADAPTER class for Servlet(I).
yes possible below shown is the way
interface Test {
void m() throws NullPointerException;
}
class Parent {
// Parent class doesn't implements Test interface
public void m() {
System.out.println("Inside Parent m()");
}
}
class Child extends Parent implements Test {
}
public class Program {
public static void main(String args[]) {
Child s = new Child();
s.m();
}
}
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) {
// ...
}
}