Looking for inheritance solutions - java

This is my scenario in Java:
interface I{}
class A implements I{}
class B extends A{}
So, now which class needs to implement the interface's I methods? What if A and B classes share implementation?
Best regards

class A has to provide all implementations since it's not abstract. See here for more details.
class B can override any/all of those methods.
If you make A abstract (as a class), then it can provide abstract methods for those methods in the interface (essentially just declaring them as abstract) and B would provide the only implementation.

1) Class A has to implement the Interface I's method.
2) Class B can however, override these definitions if required.
3) Class A should be declared abstract if it is not implementing, in which case, Class B should implement these.

You only need to implement the I interface in the A class. Optionally you can override that implementation in the B class, but if you don't do it both classes will behave in the same way (using A implementation).

Stating implements you promise that class will implement some interface. Stating extends you allow yourself to reuse implementation from base class. extends implies implements.
So in your case you promised that A will implement I. Next you promised that B will also implement I but will use A's implementation as a base.
So, your pattern supposing that B with share some implementation with A concerning A as a source. It is ok if this is what you want.
You can also:
1) state class B implements I in this case B will be at it's own.
2) hold majority of implementation in some third class, called for instance Base, like follows
interface I {}
class Base implements I {}
class A extends Base{}
class B extends Base{}
this way A and B will be of equal rights.
3) You can hold implementation in any arbitrary class and use aggregation and decorate it:
interface I {
String method1(String a);
String method2(String a);
}
class ImplementationHolder1 // does not implement I!
{
String method1impl(String a) {};
}
class ImplementationHolder2 // does not implement I!
{
String method2impl(String a) {};
}
class A implements I {
ImplementationHolder1 h1;
ImplementationHolder2 h2;
String method1(String a) {
return h1.method1impl();
};
String method2(String a) {
return h2.method2impl();
};
}
Remember, that you should make class abstract if it implement interface not fully.
Also you can override any base class implementation in descendant class if it is not matching your needs.

Related

Cyclic Inheritance Of Interfaces

I understand why cyclic inheritance of classes is not allowed in Java but I did not understand why cyclic inheritance of interfaces is not allowed. To illustrate:
interface Foo extends Bar {/*methods and constants*/}
interface Bar extends Foo {/*methods and constants*/}
Interfaces do not need instantiation, then what prevents them from extending each other?
By the way, I read this question but this is not about interfaces but classes:
Cyclic inheritance hierarchy in Java
Thanks in advance.
No, but extension of an interface is a way of splitting up the agreement. Remember, an interface is an agreement to provide an implementation of a set of methods.
public interface A extends B {
public void myMethod();
public void myOtherMethod();
}
You're saying interface A is defined by these methods and all the methods in interface B. Now if interface B says..
public interface B extends A {}
you're saying that interface B is defined by the methods in interface A. Well what defines interface A. A couple of methods and interface B. And what defines interface B? Interface A, which is defined by a couple of methods and interface B! See where this is going?
It makes no logical sense to allow this.
Probably there are no theoretical difficulties, but this would create unnecessary complications. A few to name:
Currently traversal of class interfaces (via recursive calls of Class.getInterfaces()) is guaranteed to produce finite result, probably with repeats, but nevertheless. For example, such code is valid:
private static void fillInterfaces(Class<?> clazz, Set<Class<?>> set) {
if(clazz == null) return;
for (Class<?> iclass : clazz.getInterfaces()) {
set.add(iclass);
fillInterfaces(iclass, set);
}
fillInterfaces(clazz.getSuperclass(), set);
}
public static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
Set<Class<?>> result = new HashSet<>();
fillInterfaces(clazz, result);
return result;
}
Similar code is already written and working in many places. With your proposal supplying the circular interface here would cause an infinite recursion.
Currently (in Java-8) interface can define a default implementation for its parent interface as well, replacing parent implementation if necessary. For example:
interface A {
default public String getX() {return "A";}
}
interface B extends A {
default public String getX() {return "B";}
}
static class C implements A, B {} // ok, C.getX() returns "B"
If now A extends B, then A wins:
interface A extends B {
default public String getX() {return "A";}
}
interface B {
default public String getX() {return "B";}
}
static class C implements A, B {} // ok, C.getX() returns "A"
But what if both A extends B and B extends A? Who will win? What new C().getX() will print? Or should it be new type of compilation error?
In general it seems that such feature would bring more problems than produce benefits.
See Java Language Specification 9.1.3 Superinterfaces and Subinterfaces :
An interface I depends on a reference type T if any of the following is true:
I directly depends on T.
I directly depends on a class C that depends on T (§8.1.5).
I directly depends on an interface J that depends on T (using this definition recursively).
It is a compile-time error if an interface depends on itself.
If circularly declared interfaces are detected at run time, as interfaces are loaded, then a ClassCircularityError is thrown (§12.2.1).
As for why, I like Andy Turner's comment:
If Foo extends Bar, then every instance of Foo is also a Bar. If Bar extends Foo, then every instance of Bar is also a Foo. If both were allowed to be true, then the only way the two conditions can be satisfied is if Foo == Bar.

OOP interface inheritance

My question is that can one interface extend another interface or it implements another interface.
interface A {
}
interface B extends A {
}
OR
interface B implements A {
}
Barring Java 8 extensions, an interface doesn't implement anything.
So therefore extends is the correct term.
An interface can only extend another interface, since an interface cannot contain any implementation.
interface ParentInterface{
void myMethod();
}
interface SubInterface extends ParentInterface{
void anotherMethod();
}
Yes, they can via the extends keyword, as interfaces can't implement any methods, only declare their signatures.
interface A {
public void foo();
}
interface B extends A {
// You don't implement the methods from A here
public void bar();
}
class C implements B {
public void foo(){
}
public void bar(){
}
}
Any class that then implements B must then implement the methods from A as well.
Yes, an interface can extend another interface in Java.
// this interface extends from the Body interface:
public interface FourLegs extends Body
{
public void walkWithFourLegs( );
}
Well but we must think,
When would we want an interface to extend another interface
We know that any class that implements an interface must implement the method headings that are declared in that interface. And, if that interface extends from other interfaces, then the implementing class must also implement the methods in the interfaces that are being extended or derived from.
So, in the example above, if we have a class that implements the FourLegs interface, then that class must have definitions for any method headings in both the FourLegs interface and the Body interface.
Question part 2:Interface do not Implement another interface,Because
Implements denotes defining an implementation for the methods of an interface. However interfaces have no implementation so that's not possible.
In terms of Inheritance in case of "INTERFACE" they always extends they never implement anything.

Interfaces usage

Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class? Therefore having object A which uses the interface and object B which does not use it.
Thanks
Updated:
Assuming you have a Professor class and this class implements an interface called Employer, which has employ(rAssist x) abstract method.
Now I want to instantiated 2 objects from the Professor class implementing this interface Object A - Professor can employ a research assistant and Object B - Professor cannot employ research assistants.
Can you have a class which implements an interface, and choose whether to use the methods in the interface during instantiation of this class?
No, if class C implements the interface, then all instances of C will provide the methods declared in the interface.
What you can do is something like
class MyClass implements MyInterface {
#Override
void interfaceMethod() {
System.out.println("Interface method");
}
}
and then do
MyClass x = new MyClass();
MyClass y = new MyClass() {
#Override
void interfaceMethod() {
throw new UnsupportedOperationException();
}
};
In effect, x supports the use of interfaceMethod while y does not. Note however that...
The usage of y.interfaceMethod is not prevented at compile-time, i.e. it will not be enforced by the type system.
With this solution, you are in fact creating an (anonymous) subclass of MyClass and assigning an instance of it to y.
Do you mean you want class A and Class B to implement a common Interface but you dont want to implement all methods in Class B?
An Interface in simple terms means it is sort of a contract and all the classes which implement it should follow that contract.So if you want Class B to implement the interface , Class B should also follow the same contract. But if you dont want to implement any methos you can always do this.
class ISampleInterface {
void sampleMethod();
void optionalMethod();
}
Class A implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
//Your Implementation
}
}
class B implements ISampleInterface {
void sampleMethod() {
//Your Implementation
}
void optionalMethod() {
throw new UnsupportedMethodException();
}
}
No, that's not the point of an Interface.
An Interface is contract that guarantees that implementations WILL implement it's signature
The idea of interface is to establish a obligation for the class that implements the interface.
If your's is a requirement, you can use the java.lang.reflect.Method reflection class to change the visibility of the method at runtime. However, this is not a clean way.
1. Interfaces were introduced in Java because Multiple Inheritance was not allowed in Java.
2. But as far as Design Pattern are concerned, following are the uses..
- To implement certain Roles.
Consider Dog a Super class, but then Pet dog and Wild dog can be interfaces, which
can be implemented by the Sub Classes of Dog class.
- Used when Behaviors keeps changing.
Consider you have a Class Drawing, and paint method() in it, now paint can be stroking, shading, etc...
You must Encapsulate such behaviors in an Interface or an Abstract class.

How to force implementation of a nested abstract class in an abstract class in Java?

I'm new to Java but used to OOP programming. Is there a way I can force implementing an abstract class nested into another abstract class like in the code below :
public abstract class A
{
public abstract class B extends C
{
#Override
public abstract void foo();
}
}
I would like B to be implemented in each subclass of A. Is it possible?
Thank you for your help,
If I read your question correctly, where you want each sub-class of A to CONTAIN a subclass of B, there is not a direct way to do this. However, you could do something like the below:
public abstract class A
{
public abstract class B extends C
{
#Override
public abstract void foo();
}
protected abstract B getBInstance();
}
Because this forces sub-class of A to return an instance of B, they must have access to some sub-class of B.
However, you should really ask yourself why A should care about its sub-classes implementing B unless A uses B in some way which would require the above.
Yes, make B an interface, as shown in When an Abstract Class Implements an Interface.
This is not possible. The A class should only provide what behaviour an instance of A has (either through the abstract or implemented methods). It should not state anything about how A is implemented.
It's not even clear how this would be useful either since you could not call the implemented class B so it would need to be named something else meaning it's existence could be ignored.

What (not) to declare when implementing an interface with an abstract class?

I have an interface A, for which I have to supply a few different
implementations. However, those implementations share some helper methods, so
I moved those methods to an abstract base class.
Interface A {
void doX();
}
abstract Class B implements A {
protected void commonY() {
// ...
}
#Override
public abstract void doX();
}
Class C extends B {
#Override
public void doX() {
// ...
}
}
Class D extends B {
#Override
public void doX() {
// ...
}
}
My code works as expected, but I have a few questions:
Should I declare the abstract Method doX() in Class B? Why (not)?
Should I also explicitly declare "implements A" on Class C and D? Why (not)?
I think it would be better to do it as follows:
Interface A {
void doX();
}
abstract Class B {
protected void commonY() {
// ...
}
}
Class C extends B implements A{
public void doX() {
// ...
}
}
Class D extends B implements A{
public void doX() {
// ...
}
}
You shouldn't mix the interface (signature of methods) with the implementation.
Should I declare the abstract Method doX() in Class B? Why (not)?
No. It's an abstract class - defining the interface will mean that all subclasses will need to implement those methods. In other words, it's redundant.
Should I also explicitly declare "implements A" on Class C and D? Why (not)?
No, again - because your superclass (Abstract base class) implements that interface, your concrete subclasses will be guaranteed to implement that interface.
I'll just throw in the other option.
Turn abstract class B into an AUtil class that doesn't implement A. The method signatures may require an additional argument of type A to work with.
C and D implement A, and instantiate an AUtil internally. This does allow C and D to extend other classes.
I agree with JeeBee: consider implementing your helper methods somewhere other than an abstract base class.
If your helper method commonY() only exists in abstract base class B, all classes which implement Interface A will have to also extend base class B in order to take advantage of that implementation of commonY(). But, you might not always want to be forced to extend class B.
Also, what if you want to change the implementation of commonY() in the future? You will then affect lots of implementations of interface A. But if you don't control all these implementations of interface A, you may affect their functionality (in a bad way) without intending to.
Using an abstract base class in this situation may simply take away some flexibility without giving you anything in return.
An abstract class implementing an interface must implement that interface. Specifically, it must have a public method for every method-name-and-signature specified in that interface.
Inheritance is transitive. You do not need to write that class C implements interface A if class C derives class B which implements interface A. However, there isn't much harm to it either.
I would not declare doX() in B and not add "implements A" on C and D because you should not repeat yourself.
The abstract doX() in B adds nothing, as it's already specified by "implements A". The same is true for adding "implements A" to C and D.
The only possible use for those clauses would be documentation: If you want to make it very explicit that C (or D) is-a A, then you could add the implements, but you should be aware that it really doesn't matter to the compiler.

Categories