Using Marker interface for making methods more generic - java

For example,
I have a method in an abstract class with the following signature.
Set<CarRecommendation> generateRecommendations(String accountId){
// do something
}
To make the above method generic and compatible for different types of Recommendation, I'm thinking of using an empty interface and let CarRecommendation and BikeRecommendation implement it.
public interface Recommendation {
}
public class CarRecommendation implements Recommendation{
// more stuff
}
public class BikeRecommendation implements Recommendation{
// more stuff
}
so that I can change the method signature in the abstract class to the following
Set<? extends Recommendation> generateRecommendations(String accountId)
Is it a good practice to define marker interfaces for the sole purpose of making methods generic? If not, what would be a better approach? Thanks.

Related

Implement clone defined in an Interface returning the concrete class?

I am reading DesignPatterns ('GoF patterns') and implementing the Example MazeGame. While reading about Prototypes, I ran into a thing writing the clone method (cloneIt()).
First of all my structure:
Interface: MapSite
AbstractClass: AbstractMapSite
Concrete Impl: Room, Door, Wall
My plan is to define cloneIt in MapSite and give a default implementation (simply calling Object.clone()), which can be overidden in the concrete classes. Now the cloneIt() method always returns the interface type MapSite.
Is there a way to 'force' Java to return the concrete class type (Room, Door, Wall) eventhough the method from the abstract class is used? This may avoid castings.
I know about the pros of Interfaces and why they are used :)
Solution
As #philipp-wendler and #davidxxx suggested, I ended up using generics. In case the shallow copy of Object.clone() is a problem, I override cloneIt() in the concrete class.
public interface MapSite<T> extends Serializable {
T cloneIt();
}
...
public abstract class AbstractMapSite<T> implements MapSite<T> {
public T cloneIt() {
try {
return (T) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
...
public class Wall extends AbstractMapSite<Wall> {
public Wall cloneIt(){
// special code here
}
}
My plan is to define cloneIt in MapSite and give a default
implementation (simply calling Object.clone()), which can be overidden
in the concrete classes.
Be aware : the default implementation of Object.clone() makes a shallow copy of the cloned object and you should also implement the Cloneable interface if you don't want to see a CloneNotSupportedException be thrown.
So you should override both clone() and cloneIt(). It is confusing because a single method is enough. Just keep cloneIt() and forget the clumsy clone() method.
Is there a way to 'force' Java to return the concrete class type
(Room, Door, Wall) eventhough the method from the abstract class is
used? This may avoid castings.
With Generics yes you can do it.
For example :
public interface MapSite<T>{
T cloneIt();
}
public abstract class AbstractMapSite<T> implements MapSite<T>{
...
}
public class Wall extends AbstractMapSite<Wall>{
public Wall cloneIt(){
...
}
}
You need a recursive generic type:
public interface MapSite<T extends MapSite<T>> {
T cloneIt();
}
public abstract class AbstractMapSite<T extends AbstractMapSite<T>> implements MapSite<T> {
}
public class Room extends AbstractMapSite<Room> {
public Room cloneIt() { ... }
}
This type forces non-abstract subclasses of MapSite to declare T as their own type, thus guaranteeing the correct return type of cloneIt.
You could also implement cloneIt in the abstract class if you call clone() and use an unchecked cast to T.

Serializable interface in Java

I understand that the whole point of having an interface is to force the class that implements it to implement/define all the abstract methods in that interface.
However, in the process of Object Serialization in Java (conversion into byte stream), the class the object to be serialized is an instance of must implement the Serializable interface. However, I see no methods of the interface being defined. So, is that an interface with ZERO methods, if yes, is that even possible and if yes again, what is the purpose if it has no methods?
The Serializable interface is a marker interface. If a class implements it, the runtime system knows that the class is serializable.
In modern Java this effect could now be achieved with an annotation but they were not around at the time this interface was defined.
Yes such an interface is possible. It is called a marker interface. There are other interfaces like this also.
You can have a look at
http://mrbool.com/what-is-marker-interface-in-java/28557
As I already stated, purpose of interface with 0 methods is about pure contract.
Let me explain it in next example:
Let's say we have a simple data access layer composed of multiple interfaces like:
DeletableDao, InsertableDao, UpdatableDao etc.. and implementation class like DaoImpl:
Let's say we have entity class like this:
public Person implements DaoEntity {
private int id;
private String name;
// getters and setters
}
where DaoEntity is interface with 0 methods because of pure contract:
public DaoEntity {
}
and let's say that our DeletableDao looks like this:
public interface DeletableDao<T extends DaoEntity> {
void delete(T t);
}
and implementation class:
public DaoImpl implements DeletableDao<Person> {
public void delete(Person p) {
// Delete person
}
}
What this all means? What is a purpose of DaoEntity interface? It means that only instance of DaoEntity subclass can be passed to delete method and deleted.

Should I implement all the methods present in an abstract class?

Below is the code snippet:
public abstract class MyAbstractClass {
public abstract void a();
public abstract void b();
}
public class Foo extends MyAbstractClass {
public void a() {
System.out.println("hello");
}
public void b(){
System.out.println("bye");
}
}
public class Bar extends MyAbstractClass {
public void a() {
System.out.println("hello");
}
public void delta() {
System.out.println("gamma");
}
}
There are couple of questions that I have:
Q-1 :- Should I implement ALL the methods in abstract class?
Q-2 :- Can the implementing class have its own methods?
When you extend an Interface or an Abstract class you are creating a contract of sorts with that superclass. In the contract you are saying:
"I will implement all unimplemented methods in my superclass"
If you do not, implement all the unimplemented methods, then you are breaking your contract. A way to not break your contract is make your subclass Abstract as well as a way of saying
"I have not implemented all the classes in my contract, I am going to
have my subclasses implement them".
For your class bar right now, you must implement b() or make bar an Abstract class or you are not fulfilling your contract with MyAbstractClass
The basic idea is:
Interface: None of my methods are implemented. A subclass must implement all my methods in order to implement me. (Note: I believe default interfaces have been added to Java 8 which may change this a bit)
Example:
public interface myInterface
{
//My subclasses must implement this to fulfill their contract with me
public void methodA();
//My subclasses must implement this to fulfill their contract with me
public void methodB();
}
Abstract: I may implement some of my methods, but I will also leave methods as abstract so that my subclasses must implement because they can implement those classes to suit their needs better than I can.
Example:
public abstract class myAbstractClass
{
//My subclasses must implement this to fulfill their contract with me
public abstract void methodC();
public void helloWorld()
{
System.out.println("Hello World");
}
}
Abstract classes can also extend interfaces so they can implement some of their methods. But they can also leave some of the methods unimplemented so the subclass can implement them. If you leave an interface method unimplemented, there is not need to declare it abstract, it is already in the contract.
Example:
public abstract class myAbstractClass2 implement myInterface
{
#Override
public void methodA()
{
// this fulfills part of the contract with myInterface.
// my subclasses will not need to implement this unless they want to override
// my implementation.
}
//My subclasses must implement this to fulfill their contract with me
public abstract void methodD();
}
So in essence, an abstract class doesn't have as strict a contract with it's superclass because it can delegate its methods to its subclasses.
Regular Class: (I use regular to mean non-interface, and non-abstract). I must implement all unimplemented methods from all of my superclasses. These classes have a binding contract.
Example:
public class mySubClass extends myAbstractClass2
{
#Override
public void methodB()
{
//must be implemented to fulfill contract with myInterface
}
#Override
public void methodD()
{
//must be implemented to fulfill contract with myAbstractClass2
}
public void myMethod()
{
//This is a method specifically for mySubClass.
}
}
Q-1:- Should I implement all methods in abstract class?
Yes, you must implement all abstract methods.
Q-2 :- Can the implementing class have its own methods?
Yes, you can declare own (more specfic) methods.
You not only should, but have to implement all abstract methods (if the subclass is non-abstract). Otherwise an object of that subclass wouldn't know what to do if that method was called!
The only way to prevent this is if the subclass is also declared abstract, so that it cannot be instantiated in the first place.
You don't have to implement all methods of an abstract class. But you must implement all abstract methods of it.
In fact extending an abstract class has no difference then extending a normal class. It's not like implementing interfaces. Since you're extending you are creating a subclass thus you can add as many methods and attributes as you need.
Ya definately implementing class can define its own method as well and if are not implementing all the methods of your abstract class in the derived class then mark this derived class also as Abstract
but at the end of chain you have to make one concrete class which implements all the method that was not implement in abstract sub-parent
public interface I{
public void m();
}
public abstract class A1 implements I{
//No need to implement m() here - since this is abstract
}
public class B1 extends A1{
public void m(){
//This is required, since A1 did not implement m().
}
}
public abstract class A11 extends A1{
//Again No need to implement m() here - since this is abstract
public abstract void newA11Method()
}
public class B11 extends A11{
//This class needs to implement m() and newA11Method()
}
Yes, the implementing class need only implement the methods labeled as abstract in the abstract class.
Yes you must implement all the methods present in an abstract class. As the purpose of abstract class is purely to create a template for the functions whose implementation is decided by the class implementing them. So if you don't implement them, then you are breaking the concept of abstract class.
To answer your second question, yes you can create any number of your own methods irrespective of the abstract class you are extending.
Yes, When you are implementing an Interface you will have to implement all its methods. That is the purpose of defining an Interface. And yes, you can have your own methods in the class where you implement an Interface.
Yes, when you extends abstract you should give implementation for all abstract methods which are presents in abstract class. Othrewise you should make it implementation class as abtract class.
You must implement all the abstract methods you have in the abstract class. But you can directly use the concrete methods that are implemented.
For more information please refer to the :
https://www.javatpoint.com/abstract-class-in-java

Implementing interface with just one class or more classes

Maybe its answer is obvious for most of you but I am a bit confused when implementing an interface.
Should “just one implementation class” implement “the complete set of methods”?
Forex:
public class CCSImplementation implements CCS {
public void addComment (int submissionId,int customerId, String comment, Date date) { }
public void addGeneralComplaint (int submissionId, int customerId, String description, Date date) { }
and other methods…..}
Or
- More implementation classes such as
public class Comment implements CCS {
public void addComment() {}
}
and
public class GeneralComplaints implements CCS {
public void addGeneralComplaint(){}
}
implement the interface part by part taking into account of related methods? (---I got error when implement like these)
Since a reference says
One or more classes can implement that interface...
as I said I am a bit confused.
If the class is abstract, you don't have to implement all/any of the methods:
public abstract class Comment implements CCS {
public void addComment() {}
// addGeneralComplaint() is implied as abstract
}
Depending on your need, it would be perfectly valid to define such a class, where some of the methods are implemented, but subclasses are left to implement the rest of the interface's methods.
When a non-abstract class implements an interface it must provide implementations of all the exposed by the interface methods.
If we have an abstract class A, it can implement an interface without providing method implementations of the interface-exposed methods, since all of them are abstract by default. But when this class is subclassed by a non-abstract class B, the subclass must provide the implementations of the interface-exposed method signatures.
class Comment should extends Class GeneralComplaints
or
class GeneralComplaints should extends class Comment..
If it turns out that you are using an abstract class then you don't have to use everything. From my understanding you only want to implement something if you plan on using the provided methods. It was explained to me that an interface s provided so that the user doesn't forget to use methods in their class. Hope this helps.

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.

Categories