Implementing one interface using multiple classes - java

This question was asked to me in an interview. Tired of googling here I am.
I have an interface with 100 methods. I don't want to implement all those 100 methods in a single class. Is there any way I could implement these 100 methods by using more than one class and not repeating the implementation ?
For Example :
Class A implements first 10 methods(only).
Class B implements next 10 methods(only) and so on.
Note :
1. All the classes which implements the interface must be concrete.
As far as my knowledge on java this isn't possible. He mentioned about adapter when he asked me this question. That made me think that there's a way to do it.
Can anybody clarify me on this ?

Write an adapter with empty implementation of the 100 methods
class Adapter{
//write your empty implementations here as similar to KeyListener in Java
// They have written a keyAdapter and make use of key adapter.
}
ie) class Adapter implements interface1{
public void method1(){}
public void method2(){}
.....
}
You can extend the adapter class in some other class and just override the methods.
class A extedns Adapter{
public void method1(){
}
}
ie)

The concept you describe is called partial classes and Java does not have such a concept.
Here is a similar answer: A way to implement partial classes in java

If you use Java 8 , you can define default implementations in the interface for the 100 methods like :
public interface MyInterface{
void methodA();
int methodB();
default boolean methodC(String name) {
return name.equals("Default");
}
}
Then in your concrete classes you only implements the methods you want. All other not overriden methods will use the default implementation from the interface.
You will have to write 100 default implementations in the interface but it will save you the need to also write 100 implementations in every concrete class implementing that interface.
Again, this is only available since Java 8.

Write all the classes (A, B, C, D, E each implement 20 methods) witch extend one another without implementing the interface I:
I
|
A <- B <- C <- D <- E
And only the last one implements the interface.
Simpler exemple with only 2 methods:
public interface I {
void a();
void b();
}
public class A {
public void a() {
}
}
public class B extends A implements I {
public void b() {
}
}

If the interface methods defined with default implementation ;
public interface I {
default void a(){
//implementation
}
default void b(){
//implementation
}
default void c(){
//implementation
}
//97 more
}
public class A implements I{
#override
public void a() {
}
}
public class B extends A {
#override
public void b() {
}
public class C extends B {
#override
public void c() {
}
}
Even without inheritance classes can be independent from each other and they can provide implementation for different methods

You are correct - any concrete class must implement all methods, so the only way you can not do it is either extend the class that implements given interface and override some of the methods in subclass or implement methods calling implementations from other classes

Related

Creating an intance of a Class via method of an Interface implemented by that class

I want to call the constructor of a class inside the method of an interface.
For example, if I have two classes B and C and they both implement SomeInterface, so that each of them has method foo().
interface SomeInterface {
public SomeInterface foo();
}
class B implements SomeInterface {
public B(int fst, int snd) {}
#Override
public SomeInterface foo() {
return new B(1, 1);
}
}
class C implements SomeInterface {
public C(int fst, int snd) {}
#Override
public SomeInterface foo() {
return new C(1, 1);
}
}
And let's say, for the sake of this question, that I have a lot more classes that implement SomeInterface and they all do the same thing, that is return new <nameoftheclass>(1,1)
and all these classes extend the parent class A.
Is there a way for me to create only one method in A such that if any of these classes use the foo method that is found in A it will call their constructor and just like that save me lines of code?
You can do something like this with reflection, although it will be prone to failure.
public SomeInterface foo() {
Constructor<? extends SomeInterface> c = getClass().getConstructor(int.class, int.class);
return c.newInstance( 1, 1);
}
You'll have to manage some exceptions, but is this what you're after?
The question would then be, where can this be used? Interfaces don't have a common constructor.
public interface SomeInterface{
default SomeInterface another(){
Constructor<? extends SomeInterface> c = getClass().getConstructor(int.class, int.class);
return c.newInstance( 1, 1);
}
}
That would work provided whatever the implementations try to use it have that constructor. There is no guarantee that constructor exists though. Maybe you would want it on an abstract class?
use the foo method that is found in A it will call their constructor and just like that save me lines of code?
You are getting it wrong. Class design decisions must be based on use cases and relationships of the classes in your domain. If your main criteria will be to spare some lines of code, you can end up with a coffee machine extending combine harvester because both of them have tree dimensions. Don't take a pill if you have no headache.
Parent class A that you've mentioned doesn't make any sense because method foo() returns an instance of SomeInterface interface which A doesn't implement (because if it does, its subclasses don't need to declare to implement it). I.e. A and SomeInterface are not compatible and compiler will not allow to type cast between them. Therefore, I'll omit the parent class.
As an example, the "template" you've provided might be useful, will be a situation when classes with similar functionality need to grouped together.
The interface can serve as a single entry point for the user of the code. Every class will implement the behavior defined by the interface, and only through the interface it'll be possible to get an instance of the class with a particular flavor of functionality. The actual classes will be hidden from the user.
Similarly, abstract class NumberFormat from the JDK provides a way to obtain different kinds of formatters, but actual implementations are hidden are not exposed (the approach shown below is far more simple than the actual way of how factory methods of the NumberFormat are implemented).
Note, interface and its implementations must reside in the same package.
public interface BaseInterface {
public static BaseInterface getInstance(Classifier classifier) { // factory
return switch(classifier) {
case A -> new A();
case B -> new B();
};
}
void doSomeThingUseful(); // behaviour that every class should implement
}
enum Classifier { A, B }
class A implements BaseInterface {
A() {}
#Override
public void doSomeThingUseful() {
System.out.println("Class A");
}
}
class B implements BaseInterface {
B() {}
#Override
public void doSomeThingUseful() {
System.out.println("Class B");
}
}
main() - demo
public static void main(String[] args) {
List<BaseInterface> items = List.of(BaseInterface.getInstance(Classifier.A),
BaseInterface.getInstance(Classifier.B));
for (BaseInterface item: items) {
item.doSomeThingUseful();
}
}
Output
Class A
Class B

When I extend an interface A with interface B, will A's methods be available for free to B's implementors?

I'm curious how this all works. I have an interface, let's call it A. When I look at A, it has most of the methods I need, but not all, and I don't have control over interface A, so I extend it with interface B which implements the 1 or whatever number of methods that I need on top of A.
public interface B extends A {
String doSomethingFun(String blah);
}
A has an implementation class called Client. In just a second I'm going to create my own implementation class of B called MyDefaultClient.
I then create a concrete class that implements B, like this:
#Component
public class MyDefaultClient implements B {
private A myClient;
#Autowired
public MyDefaultClient(A myClient) {
this.myClient = myClient;
}
#Override
public String doSomethingFun(String filename) {
// custom business logic
}
#Override
public String serviceName() {
return myClient.serviceName();
}
#Override
public void close() {
myClient.close();
}
}
serviceName() and close() are methods that A forces its implementors to implement. There are other methods though that have default implementations that aren't forcing me to implement them, I assume simply because they have default implementations.
At this point I have a concrete class that I can instantiate in other places and call all of both A and B's methods on it. But is that only because in the interface there are default implementations for these methods, like this?
default Blah someMethodInA(String thing) {
throw new UnsupportedOperationException();
}
If I use this code and call myDefaultClient.doSomethingFun("hello") I'm pretty certain that will do the thing I want it to do. But what about if I call myDefaultClient.someMethodInA()? Will it call the implemented method in Client, which is A's implementor? Or will it fall on the floor and complain with an UnsupportedOperationException? If the latter, is there any way I can structure this so that I can call all of A's methods from B's implementor?
If you want MyDefaultClient to inherit implementations from Client, then it has to extend Client, like this:
class MyDefaultClient extends Client implements B
{
...
}
Then, if Client implements A, you will only have to provide implementations for the new methods that B adds.
or... you can continue your current pattern and explicitly delegate all the calls you want to a field of type A, but you will have to do them all explicitly, even the methods with default implementations. The default implementations will continue the throw exceptions if you don't override them.
An interface can have any number of default methods. Check this for more details. Given below is an example to demonstrate how default methods and extending an interface work:
public interface InterfaceA {
public void toBeImplementedA();
default void hello() {
System.out.println("Hello");
}
default void hi() {
System.out.println("Hi");
}
}
public interface InterfaceB extends InterfaceA {
public void toBeImplementedB();
}
public class AnImplClass implements InterfaceB {
#Override
public void toBeImplementedA() {
System.out.println("toBeImplementedA");
}
#Override
public void toBeImplementedB() {
System.out.println("toBeImplementedB");
}
}
public class Main {
public static void main(String[] args) {
InterfaceB obj = new AnImplClass();
obj.toBeImplementedA();
obj.toBeImplementedB();
obj.hello();
obj.hi();
}
}
Output:
toBeImplementedA
toBeImplementedB
Hello
Hi
Feel free to comment in case of any doubt.
Interfaces can contain default methods. These were added to Java so that an interface could be updated without forcing implementing code to be rewritten.¹
Default methods provide an implementation if your implementing class does not implement them.
When you call methods on an object, the overridden method is always called.
Any other implementations in the super classes / interfaces are used when there is a lack of implementation.
Even if you refer to MyDefaultClient as A,
A myImplementation = new MyDefaultClient();
Under the hood myImplementation is still an instance of MyDefaultClient even though the code views it as A. Therefore your overriden method will be used when doSomethingFun is called.
#Override
public String doSomethingFun(String filename) {
// custom business logic
}
¹ Source: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

Implement multiple classes in the same interface in Java?

I have got multiple classes which each implement multiple different methods within each. Now the problem statement is that I wish to use the methods from all these (maybe around ~200 such different class files/methods) in another class file which all different methods from the above class files.
I thought that if I implement an interface which has all these various methods listed, then I just call/import/reference that single interface and can use all the methods? But I am stuck, as this solution does not seem to work.
The opposite of the above works (i.e. single class implements 2 interfaces: http://tutorials.jenkov.com/java/interfaces.html). Wish to check if the single interface can use multiple classes, without the overhead of declaring all the methods in each class that is being referenced inside the Interface?
As an example: Is there any way in which I can implement 2 different classes in the same interface, without each having the abstract class for each? As if the class is abstract, then I am unable to use the methods from it in the below example "Application" class:
Common commonClass = new ABC_FamilyGivenName();
The above is not allowed, if the ABC_FamilyGivenName class is an abstract class.
INTERFACE:
public interface Common {
void ABC_GivenNames();
void ABC_FamilyNames();
void ABC_Gender();
void ABC_BirthDay();
}
IMPLEMENTATION CLASSES:
public class ABC_FamilyGivenName extends Base implements Common {
public void ABC_GivenNames(){
// Implementation code
}
public void ABC_FamilyNames(){
// Implementation code
}
}
public class ABC_DOBGender extends Base implements Common {
public void ABC_Gender(){
// Implementation code
}
public void ABC_BirthDay(){
// Implementation code
}
}
USE IMPLEMENTED CLASS:
public class Application extends Base {
Common commonClass = new ABC_FamilyGivenName();
/* DO I NEED THIS? I THINK I DO, BUT CODE/JAVA SAYS I DO NOT
* Common commonClass = new ABC_DOBGender();
*/
public void ELP_C0050_PassportDetails(){
commonClass.ABC_GivenNames();
commonClass.ABC_FamilyNames();
commonClass.ABC_DOB();
commonClass.ABC_Gender();
}
}
I have 2 classes called ABC_FamilyGivenName & ABC_DOBGender.
I have created an interface Common.
I want to use the methods in both the above classes in another class called Application.
With the current implementation, Java wants me to add an #Override to both the ABC_FamilyGivenName & ABC_DOBGender:
IMPLEMENTATION CLASSES:
public class ABC_FamilyGivenName extends Base implements Common {
public void ABC_GivenNames(){
// Implementation code
}
public void ABC_FamilyNames(){
// Implementation code
}
#Override
public void ABC_BirthDay() {}
#Override
public void ABC_Gender() {}
}
public class ABC_DOBGender extends Base implements Common {
public void ABC_Gender(){
// Implementation code
}
public void ABC_BirthDay(){
// Implementation code
}
#Override
public void ABC_GivenName() { }
#Override
public void ABC_FamilyName() { }
}
Can I avoid the above #Override and just use the classes without these as given in the first example?
Object-oriented programming in Java requires to "override" all methods, if you are implementing a method, otherwise you may use inheritance, so not all methods must be overriden.
In your case you may put all four methods to parent class Base and then inherit them.
Then the interface class is not needed or make two different interfaces.
To implement Java interface, You should override all the abstract methods are declared into the interface. It is a basic concept of interface. Here interface Common all four methods are abstract, So you should override them. Otherwise, Java compiler will throw a compilation error. So better way can be splitting the interface into 2 parts.
It is a contractual nature of an interface the subclass who implement the interface should have all the activities of the interface. It is the main purpose of using an interface.
If you don't wanna override all the method of interface but you need to use the interface as a reference of every class, then you can use a concrete class instead of interface and inherit the concrete class to every class
To implement the below code change please make sure you use java8
public interface Common {
default public void ABC_GivenNames() {
}
default public void ABC_FamilyNames() {
}
default public void ABC_Gender() {
}
default public void ABC_BirthDay() {
}
}
IMPLEMENTATION CLASSES:
public class ABC_FamilyGivenName extends Base implements Common {
public void ABC_GivenNames(){
// Implementation code
}
public void ABC_FamilyNames(){
// Implementation code
}
}
public class ABC_DOBGender extends Base implements Common {
public void ABC_Gender(){
// Implementation code
}
public void ABC_BirthDay(){
// Implementation code
}
}
Can I avoid the above #Override and just use the classes without these
as given in the first example?
No, in java you have to implement all methods of interface unless its abstract class
as suggestion you can create two separate interfaces,
for more detail see : not implementing all of the methods of interface. is it possible?
You can provide an empty implementation for all the methods of an interface in other class called Adaptor class. And you can extend that adaptor class in ABC_FamilyGivenName class and ABC_DOBGender class.
class Adaptor implements common
{
public void ABC_GivenNames() {
}
public void ABC_FamilyNames() {
}
public void ABC_Gender() {
}
public void ABC_BirthDay() {
}
}
IMPLEMENTATION CLASSES :
public class ABC_FamilyGivenName extends Adaptor{
public void ABC_GivenNames(){
// Implementation code
}
public void ABC_FamilyNames(){
// Implementation code
}
}
public class ABC_DOBGender extends Adaptor {
public void ABC_Gender(){
// Implementation code
}
public void ABC_BirthDay(){
// Implementation code
}
}
interface Icalculate{ //interface
calculate(operand1:number,operand2:number):number
}
class Add implements Icalculate{ //addition
calculate(operand1: number, operand2: number): number{
return (operand1 + operand2);
}
}
class Sub implements Icalculate{ //subtraction
calculate(operand1: number, operand2: number): number{
return (operand1 - operand2);
}
}
class Mul implements Icalculate{ //multiplicationn
calculate(operand1: number, operand2: number): number{
return(operand1*operand2);
}
}
class Div implements Icalculate{ //Division
calculate(operand1: number, operand2: number): number{
return(operand1/operand2);
}
}
let a = new Add;
let b = new Sub;
let c = new Mul;
let d = new Div;
class Calculator { //main class
operator: Icalculate;
operand1: number;
operand2: number;
constructor(a: number, b: number, operator: Icalculate) {
this.operand1 = a;
this.operand2 = b;
this.operator = operator;
let op = this.operator;
console.log(op.calculate(this.operand1, this.operand2));
}
}
const cal=new Calculator(1,1,a);

How do you implement inference with extensions <java>

I was trying to figure out how to do simple implementations and I thought, what if the interface extends to another interface?
so for example,
public interface A{
public void a();
}
public interface B{
public void b();
}
public interface C extends B, A {
public void c();
}
If I was to implement interface C on another class what do I have to do?
I tried this from reading other threads:
public class Example<E extends B&A> implements C{
public void c(){
}
}
Which doesn't seem to be right.
Whats wrong with ... simply implementing all interfaces?
public class Example implements C {
#Override
public void a(){ }
#Override
public void b(){ }
#Override
public void c(){ }
}
In other words: what do you think to gain from making Example a generic type in the first place?!
Meaning: if there is a deeper problem that I don't see - you should consider updating your question and explain what you intend to do (to avoid solving a xy problem here). If there is no deeper problem, go with the most simple solution (like the one shown above).
If you want your Example class to implement C... all you need to do is to say implements C. The type variable is quite separate and irrelevant to this:
public class Example implements C { ... }
But looking at your class signature:
public class Example<E extends B&A> implements C
E is a type variable which allows you to handle references to classes implementing both B and A (but not C).
For example, if there is a method in Example taking an E as a parameter:
void someMethod(E e)
then you can have the following in its body:
void someMethod(E e) {
e.a(); // OK.
e.b(); // OK.
// e.c(); // Compiler error, E doesn't implement C.
}

Any established practices on overcoming the lack of multiple inheritance in Java?

I have a classic diamond inheritance problem where
A
/ \
B C
\ /
D
are all interfaces, and I have
AImpl(A)
| \
| \
BImpl(B) CImpl(C)
| \
| \
DImpl(B,C) \
| F(C)
|
E(B,C)
where class E implements both interfaces B and C, but F implements only interface C.
Due to the lack of multiple inheritance, I currently have duplicated functionality in DImpl and CImpl.
I just fixed a bug in CImpl, but forgot to do the same for DImpl. Obviously remembering to always copy code from CImpl to DImpl and vice versa is not very sustainable as the code base keeps growing. Are there any established best practices for putting the shared code of both in a single place, despite the disallowance of multiple inheritance?
EDIT -- Solution with multiple inheritance would have been to have DImpl inherit CImpl.cFunction() instead of redefining DImpl.cFunction as a copy of CImpl.cFunction
EDIT 2 -- Sample code:
public interface Animal {
public void eat();
}
public interface FlyingAnimal extends Animal {
public void fly();
}
public interface RunningAnimal extends Animal {
public void run();
}
public interface Monster extends FlyingAnimal, RunningAnimal {
public void roar();
}
public class AnimalImpl implements Animal {
#Override
public void eat() {
...
}
}
public class FlyingAnimalImpl extends AnimalImpl implements FlyingAnimal {
#Override
public void fly() {
...
}
}
public class RunningAnimalImpl extends AnimalImpl implements RunningAnimal {
#Override
public void run() {
...
}
}
public class MonsterImpl extends FlyingAnimalImpl implements Monster {
#Override
public void run() {
...
}
#Override
public void roar() {
...
}
}
public class ScaryMonster extends MonsterImpl implements Monster {
public void sneakAround() {
...
}
}
public class Human extends RunningAnimalImpl implements RunningAnimal {
public void scream() {
...
}
}
Now if I find a bug in RunningAnimalImpl.run() and I fix it, I have to remember to copy the fix over to MonsterImpl.run().
This is a very poor design. You should not have a diamond structure in the first place just because it is possible in interfaces.
One of the basic principle of OOP is
Prefer composition over inheritance!
What I am saying is you don't need interface D at all. Wherever you need to use DImpl simply provide reference to interface A and then based on your runtime need pass BIml or CImpl instance to it. That way all you have to change is BImpl code or CImpl code for bug fix and it will be used anywhere you are using DImpl instance today.
As per your comment the code would be something like -
public class ScaryMonster {
Animal animal;
public ScaryMonster(Animal animal) {
this.animal = animal;
}
public void fly() {
if(animal instanceof FlyingAnimal ) {
((FlyingAnimal )animal).fly();
}
else {
throw new Exception("This mosnter cannot fly");
}
}
public void run() {
if(animal instanceof RunningAnimal ) {
((RunningAnimal )animal).run();
}
else {
throw new Exception("This mosnter cannot run");
}
}
public void sneakAround() {
...
}
}
If you want your monster to both fly and run pass instance of MonsterImpl to the constructor. Note now ScaryMonster does not extend or implement anything.
This is what I am saying - Prefer composition over Inheritance!.
In Java 8 you can implement default methods within interfaces so if you have an interface with common implementations just define them inside of the interface and override them whenever you need to change it up a bit. Of course this is assuming you are using Java 8.
For example:
public interface A {
default void cFunction(){
System.out.println("Calling A.cFunction");
}
}
public class DImpl implements A {
}
DImpl can call cFunction and it will default to calling the interfaces implementation.
In the case which 2 interfaces have a method with the same signature you can call them by referencing the interface name along with the method such as A.super.cFunction()
More meaningful example:
public interface Driveable {
default void start(Vehicle vehicle){
System.out.println("Starting my driveable thing");
vehicle.mileage++;
}
}
public interface Machine {
default void start(){
System.out.println("Starting my machine");
}
}
public class ElectricCar extends Vehicle implements Driveable, Machine {
public void start(){
Driveable.super.start(this);
}
}
public class DIYCar extends Vehicle implements Driveable, Machine {
public void start(){
System.out.println("instant fire");
}
}
As you can see you can implement a default method in your interface and use it within your concrete class. In this scenario an ElectriCar is Driveable and a Machine but we want it to use the Driveable start() method because at the end of the day no matter how many machines (computers) are in our car, we still just want to drive it.
This is just an example and although the example may be a bit strange I hope it helps get the point across of being able to implement default methods.
UPDATE for your example source:
In your case of your Monster and Animal being able to run, you should have a RunnableCreature interface with an implementation of run(). This way if a Monster and Animal run the same they can reference the default run() method, otherwise it can override it and implement its own.
If you need your default method to manipulate variables two (or more) of your classes that have the same run() method would have common attributes and therefore should have a common base class. You can pass this base class to the default method and manipulate its variables as needed.
Don't implement C in D, instead of inheritance compose it within D. In that way you dont duplicate your code and have just one implementation of C.
If you somehow needs to inherit from C (which i think you would need to review design then), then i would still suggest you compose C and implement all the methods of C within D and delegate calls via composed object.
A common alternative would be to use composition instead of inheritance. Does it make sense to say that D is a B and is also a C? Does D really need to expose every public method contained in B and C? If the answer to any of these questions is no, then inheritance is not the right tool for the job.
If you want to read further about the advantages of composition, check this chapter from Effective Java: Favor composition over inheritance

Categories

Resources