Interfaces usage - java

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.

Related

default method in interfaces

For a while I have been puzzled as to why we need default methods in Interfaces, and today I was reading about it. Even though few of my questions are answered, I still have a few queries.
Let's take a simple example, I've an interface1. Class A and class B implement interface1. interface1 has a method X.
interface interface1{
void methodX();
}
class A implements interface1{
#override
public void methodX(){
//something
};
}
class B implements interface1{
#override
public void methodX(){
//something
};
}
From what I understood, since adding a new method Y to interface1, would have broken Class A and class B, default methods were introduced. This means that now I can add a default method, without the need for modifying Class A and Class B. This also means that the default method has to be generic enough to do whatever we expect it to do, for both class A and class B.
Now, let's consider that we normally add functions in interface so that we can provide a class specific implementation to them by overriding it. So basically, if I am adding a method Y in an interface as default, then I will expect class A and class B (or class A/ClassB) to override the method.
Which means, I will be modifying Class A/Class B or both.
This is what confuses me. This could have been handled by creating a new interface and modifying 1 (or both) class(es) to implement that new interface (interface 2 extending interface1), and then provide implementation for the same in the class.
interface interface2 extends interface1{
void methodY();
}
class A implements interface2{
#override
public void methodY(){
//something
}
}
class B implements interface1{
#override
public void methodX(){
//something
};
}
How does default method, actually help us in not modifying the classes which implements it.
Default methods provides "base" implementation of some behaviour which can be composed of existing methods at given interface. For example, you have an interface with add method. This is enough to provide default implementation for addAll behaviour:
default void addAll(Collection<? extends E> c) { for (E e : c) { add(e); } }
Another example can be sort method in List, which can be implemented by provided methods: get(int), set(int,E), size(). Subclass might override this default implementation in order to provide more efficient sorting based on specific list properties. In LinkedList you can take advantage of attaching/detaching nodes (no need to shift an elements on right when inserting or removing node), in ArrayList you can take advantage of super fast access of element at any index).
If you mandate all the implementing classes to override the new method, then it should (if there is no valid default implementation) not be a default method.
But, the approach you have said in which to create a new interface that extends the existing one and making the classes that wish to override the new method(s) by changing the interface type they implement will be problematic since the new method is part of the new interface, you cannot access it when you have the parent/base interface type.
Example:
Existing code:
interface Base {
void m1();
}
class A implements Base {
#Override
public void m1() {
....
}
}
class B implements Base {
#Override
public void m1() {
....
}
}
You create the following interface
interface ExtendedBase extends Base {
void m2();
}
Only class A wants to implement m2. So, it becomes
class A implements ExtendedBase {
#Override
public void m1() {
....
}
#Override
public void m2() {
....
}
}
All is good so far.
When you have a method that takes an object of type Base, you can only call m1 on it (irrespective of you pass object of type A or B)
void someMethod(Base base) {
base.m1();
//base.m2(); won't work
}
To actually make use of m2 elsewhere, you need to change Base to ExtendedBase which would mean that you can no longer pass a B to it. So, you have made all classes implement m2 anyway.
Since a default method is defined in an interface, it can only access instance methods also defined in the same interface. Hence, it can only invoke functionality that is actually provided by the implementing classes (in your example A and B).
The default method does not "change" the classes' behavior, it extends it by accessing existing, properly defined behavior.
So basically, if I am adding a method Y in an interface as default, then I will expect class A and class B (or class A/ClassB) to override the method.
This wrong.
The idea of default method is to introduce new method without break compatibility with old code.
Existing implementation classes do not need to be modified to work with new default method.
This could have been handled by creating a new interface and modifying 1 (or both) class(es) to implement that new interface (interface 2 extending interface1), and then provide implementation for the same in the class.
Then you have to touch / modify the implementation class. That's what default method try to avoid.

Access the same method among different classes?

I am programming a simple platformer game, and I have several types of platforms. I created a class for the most simple type and made the rest subclasses, with the only difference between each class being the value of their variables (so they all share the same variable and method names).
In my collision detection, I loop through a HashMap. Within that HashMap are ArrayLists of the instances of each class. But when I use a nested loop to loop through try to call their methods implicitly, I have found that I cannot access these methods without explicitly declaring which class I want to call the method from.
I have done research, although the only way I can see of doing this is to loop through the instances of each class separately, meaning one loop per class; I would rather not do this, since it would be a lot more code than I feel is necessary.
In order to be able to call a common method on classes of different types you need to give your objects a common supertype declaring the common method - i.e. they should have a common superclass, or implement a common interface.
Interfaces provide an easier way of declaring common functionality, because a class can implement multiple interfaces, but it can extend only one class.
Provide an interface with the common method, then declare the map to use objects of that interface, i.e.
interface CommonInterface {
void commonMethod(int arg);
}
class One implements CommonInterface {
public void commonMethod(int arg) {
...
}
}
class Two implements CommonInterface {
public void commonMethod(int arg) {
...
}
}
Here is what you can do now:
Map<String,CommonInterface> myMap = new HashMap<>();
myMap.put("one", new One());
myMap.put("two", new Two());
for (Map.Entry<String,CommonInterface> e : myMap.entrySet()) {
System.out.println(e.getKey());
CommonInterface c = e.getValue();
c.commonMethod(123);
}
Simple, make each platform class implement an IPlatform interface or extand a base class. Look up java polymorphism and interfaces.
Are your subclasses overriding the common methods from the super class?
In other words, are your subclass' common methods declared in your simpler class?
If it is the case, you can simply call the method as if it is a simple class:
public abstract class Fruit {
public abstract void method();
}
public class Apple extends Fruit {
#Override
public void method() {
System.out.println("I'm an apple");
}
}
public class Orange extends Fruit {
#Override
public void method()
System.out.println("I'm an orange");
}
}
Using this you can simply call your method from any fruit, since it has your method declared. No need to know which fruit it is. The following code:
Fruit fruit = new Orange();
fruit.method();
will output: "I'm an orange".

Is there a way to guarantee an interface extends a class in Java?

Suppose I have the following situation:
public abstract class Vehicle {
public void turnOn() { ... }
}
public interface Flier {
public void fly();
}
Is there a way that I can guarantee that any class that implements Flier must also extend Vehicle? I don't want to make Flier an abstract class because I want to be able to mix a few other interfaces in a similar manner.
For instance:
// I also want to guarantee any class that implements Car must also implement Vehicle
public interface Car {
public void honk();
}
// I want the compiler to either give me an error saying
// MySpecialMachine must extend Vehicle, or implicitly make
// it a subclass of Vehicle. Either way, I want it to be
// impossible to implement Car or Flier without also being
// a subclass of Vehicle.
public class MySpecialMachine implements Car, Flier {
public void honk() { ... }
public void fly() { ... }
}
Java interfaces cannot extend classes, which makes sense since classes contain implementation details that cannot be specified within an interface..
The proper way to deal with this problem is to separate interface from implementation completely by turning Vehicle into an interface as well. The Car e.t.c. can extend the Vehicle interface to force the programmer to implement the corresponding methods. If you want to share code among all Vehicle instances, then you can use a (possibly abstract) class as a parent for any classes that need to implement that interface.
You could rearrange your classes and interfaces like this:
public interface IVehicle {
public void turnOn();
}
public abstract class Vehicle implements IVehicle {
public void turnOn() { ... }
}
public interface Flier extends IVehicle {
public void fly();
}
This way all implementations of Flier are guaranteed to implement the protocol of a vehicle, namely IVehicle.
If you have control on the Vehicle classes just extract Vehicle as an interface and then provide a base implementation.
If you have no control over Vehicle class, for example because it is part of a framework you are using or a third party library, it's not possible to do in Java.
The closest thing you can do is using Generics multiple wildcards notation.
<T extends Vehicle & Car>
But you can't really apply it directly to Car unless you do something like this:
public interface Car<T extends Vehicle & Car>() {
T self();
}
Which is bot weird and do not enforce the self method to actually return self, it's just a strong hint/suggestion.
You would implement a Car like this:
public class CitroenC3 extends Vehicle implements Car<CitroenC3> {
#Override
public CitroenC3 self() {
return this;
}
}
one can use a Car<?> like this:
Car<?> car = obtainCarInSomeWay();
Vehicle v = car.self();
Car c = car.self();
they should be both valid syntax.
What the compiler enforce here is that what you specify in Car<WHICH> as WHICH must both extend Vehicle and implement Car. And by adding self() you are saying to the programmer that the T object is supposed to be the object itself, thus forcing the wildcard instance to match the class if he want to be compliant with the specification.
in Java 8 you can even define a default implementation for the self method.
I also wish there was a better way to handle something like this.
It's a strange requirement, but you can accomplish something of the sort with Generics:
<T extends MyInterface & MyAbstractClass>
This question shows that you haven't grasped the essence of interface and class. Forgetting the concrete Java syntax right now, all you need to understand first is that: interface is a set of protocol, which should be implementation-agnostic. It makes no sense to let an interface extend a class(which is implementation-oriented).
Back to your concrete question, if you want to guarantee that a Flier is always a kind of Vehicle, just change the latter to an interface and let former extends it(It does make sense to extend one protocol from the other protocol). After that, you may create any class(abstract or concrete) that implements Vehicle or Flier.
Define a new Package
Create a new interface (ie. HiddenOne) with scope "default" with a method "implementMe(HiddenOne)"
Move Vehicle and Flier to the new Package.
Inherit Vehicle and Flier from HiddenOne
Implement the method implementMe in Vehicle.
Now: Whenever you like to implement from "Flier" you must extends from Vehicle !
(because only Vehicle can implement implementMe).
This is tricky but works great.

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