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.
Related
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.
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.
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.
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.
Can I implement abstract methods in an abstract base class A in java?
If the answer is yes and there is an implemented abstract method in a base class A and there is a derived class B from A (B is not abstract). Does B still has to implement that base abstract method?
If I understand your question correctly, Yes.
public abstract class TopClass {
public abstract void methodA();
public abstract void methodB();
}
public abstract class ClassA extends TopClass {
#Override
public void methodA() {
// Implementation
}
}
public class ClassB extends ClassA {
#Override
public void methodB() {
// Implementation
}
}
In this example, ClassB will compile. It will use it's own implementation of methodB(), and ClassA's implementation of methodA(). You could also override methodA() in ClassB if desired.
You could have two abstract classes, X and Y, where Y extends X. In that case it could make sense for Y to implement an abstract method of X, while still being abstract. Another non-abstract class Z could extend Y. However, in your example, for A to implement its own abstract methods is a contradiction, the point of making them abstract is so it doesn't provide implementations, it just specifies what the method signatures should look like.
If you implement an abstract method it's not really abstract any more, so no.
Abstract classes can have regular methods. If you want to implement some of the methods of class A and leave rest of the methods abstract, you can do this. However, abstract methods cannot have a body, therefore if you mark a method as abstract, then it has to be implemented by a subclass, you can't implement them in the abstract class. However, you can have an abstract class without abstract methods, then subclass only needs to extend it.
Yes, you can implement abstract methods in a class which is declared as abstract. If a class is declared abstract that does not mean all its method must be abstract.
For a concrete sub class, it is not mandatory to implement the abstract methods that are already implemented by one of their super class.
No. Abstract methods are meant to be defined by the subclass(es). For more information, see Abstract Methods and Classes. However, you can define a method in the base class and have the subclass(es) override it, if required.
Yes, but it can't be abstract any more. Abstract means there is no implementation.
What you can do is:
interface I {
void meth();
}
//and
abstract class A implements I {
public void meth() {
//implementation
}
}
Or:
abstract class A {
public abstract void meth();
}
//and
abstract class B extends A {
public void meth() {
}
}
If A already has an implementation, you can override it in B (if B is concrete), because B inherits that default implementation from A.