Java Inheritance Dilemma - java

I'm currently working on an Android SDK with essentially two variations, base variation (for third-party developers) and privileged variation (to be used internally).
The privileged SDK just adds additional functionality that the third-party developers do not have direct access to.
My idea was to use macros to selectively remove functionality but Java does not support that.
My next idea was to take the base variation and just extend classes and interfaces in there to produce the privileged variation.
My current issue is as follows using the inheritance approach (which has produced a code smell that indicated to me that there is a probably a better solution):
An instance of BaseAPI has an instance of BaseInterface, which in some of its methods use BaseDevice as parameters.
The privileged SDK has an instance of PrivilegedAPI, PrivilegedInterface, and PrivilegedDevice.
The problem comes with the idea of wanting the interfaces to take either instances of either BaseDevice or PrivilegedDevice.
I would ideally like this BaseInterface:
public interface BaseInterface {
void deviceConnected(BaseDevice device);
}
And this PrivilegedInterface:
public interface PrivilegedInterface extends BaseInterface {
//overwrites deviceConnected in BaseInterface with PrivilegedDevice
#Override
void deviceConnected(PrivilegedDevice device);
}
But I cannot override deviceConnected with a different parameter of PrivilegedDevice in PrivilegedInterface.
Another idea I had was to utilize build flavors to hide functionality but this didn't seem to fit either.
Any ideas?

Create an extra method in the interface:(this is a concept of method overloading)
public interface BaseInterface {
void deviceConnected(BaseDevice baseDevice);
void deviceConnected(PrivilegedDevice privilegedDevice);
}

I think you need to abstract away the device class.
public interface Device {
void deviceConnected();
}
public class BaseDevice implements Device {
BaseDevice() {
}
void deviceConnected() {
}
}
public class PrivilegedDevice implements Device {
PrivilegedDevice() {
}
void deviceConnected() {
}
}

This potentially does not solve the problem for people experiencing the same issue in the future, but the overall issue had to do with the hierarchy of my classes and some of their internals.
I was able to actually move some stuff into the BaseAPI, get rid of a class that was used inside BaseDevice, and basically restructured things in a more logical way. The end result is a few less classes and a more logical structure of my classes.
The code smell was a result of having a few over-complicated pieces in my code.

Related

Why the Class Adapter Design Pattern Can't Use an Interface Instead of Multiple Inheritance?

I've recently learned the Class Adapter pattern. In order to implement it, the language used must support multiple inheritance since the adapter class must inherit two classes, the Target, and the Adaptee. So in a language like Java, it could not be done.
But why couldn't it use an interface Target instead of a class Target? More inline with the Object Adapter pattern as well. Just switching from object composition (Adapter having the Adaptee) to single inheritance (Adapter inheriting the Adaptee).
By using an interface, I don't see the design difference, and as a result, the pattern can be used in Java.
Link to object adapter and class adapter class diagram
There's generally no reason you can't create a Class Adapter between two interfaces in Java. But first you have to be lucky enough to be in a scenario where the two APIs that need adapting are both interfaces to begin with.
An Adapter is mostly useful to bridge the gap between two existing APIs that don't belong to you. If you control one or both APIs, you can simply change one to match the other. When you need two separate APIs to be compatible, but the APIs don't belong to you, then you have to adapt what you're given, which may not be interfaces.
But why couldn't it use an interface Target instead of a class Target?
you can use interface. But then you will have duplication of code, but multiple inheritance removes duplication of code.
Let me show an example.
Our abstractions:
public interface IDuck
{
void Quack();
}
public interface ITurkey
{
void Gobble();
}
And concrete implementations:
public class Duck : IDuck
{
public void Quack()
{
Console.WriteLine("Quack");
}
}
public class Turkey : ITurkey
{
public void Gobble()
{
Console.WriteLine("Gobble");
}
}
And class adapter would look like this:
public class ClassAdapter : IDuck, ITurkey
{
public void Gobble()
{
// duplication of code
Console.WriteLine("Gobble");
}
public void Quack()
{
Gobble();
}
}
The above ClassAdapter has duplications of code. Sure we can extract this code and provide it through composition or inject Duck and Turkey. However, it brings additional dependencies and some complexity. So it is better to use object adapter pattern. Your code will be simpler. Simple code is almost always the best choice.

Java: Protected Method Before Interface

I have to design a datastructure that'll get implemented multiple times, and I've struck upon a problem.
Since my datastructure needs to have multiple versions of it, I've created an abstract class that lays the groundwork for all implementations. However, the datastructure requires a set-view of certain parts too.
The problem becomes as follows: The set needs to have different implementations depending on the implementation of my datastructure: Either the HashSet or the Collections.SingletonSet. The two implementing datastructures will then extend bits of these to do additional tasks when items are added or removed from the set. However, the abstract datastructure also requires a way to internally remove elements from this set such that this extra work isn't done. For this I'd like to add a protected method to the set, but I can't!
To illustrate, here's some sample code relating to the type of datastructure I'm creating:
public abstract class AbstractEdge {
public abstract AbstractSetView destination(); //Gives a subclass of AbstractSetView in implementations.
public void doStuff() {
destination().removeInternal(foo);
}
public abstract class AbstractSetView implements Set<Vertex> {
protected abstract void removeInternal(Vertex vert);
}
}
public class Edge extends AbstractEdge {
public SetView destination() {
return new SetView();
}
public class SetView extends AbstractSetView,Collections.SingletonSet<Vertex> { //Doesn't work this way.
protected void removeInternal(Vertex vert) {
//Do stuff.
}
}
}
public class HyperEdge extends AbstractEdge {
public SetView destination() {
return new SetView();
}
public class SetView extends AbstractSetView,HashSet<Vertex> { //Doesn't work this way.
protected void removeInternal(Vertex vert) {
//Do stuff.
}
}
}
These are the options I've considered:
As above, extending from multiple classes isn't allowed.
Making the AbstractSetView an interface causes the removeInternal() method to become public, which is undesirable.
Making SetView extend only AbstractSetView and implement everything myself... twice. But this requires me to basically include HashSet and SingletonSet implementations, as an inner class, which is extremely ugly.
Surely the designers of Java made some way around this, to enable me to use their built-in Set implementations? What am I overlooking?
No, they did not "make some way around this" because they didn't see any obstacle, problem, or limitation. According to them, multiple inheritance was not really needed in the language because at least 85% of the time it is used when what really corresponds is composition. 14% of the remaining cases can be solved through interfaces and non-natural use of composition, and 1% with code replication. True: the later is U.G.L.Y. and R.E.D.U.N.D.A.N.T. and U.N.S.A.F.E., etc, but the main objective was to create a small language that could be implemented even in embedded devices. They were not going to give this up for just 1% of the cases. IMHO, they were about right in the percentages.
To answer your second question: don't inherit, especially from library classes, when what you really need is composition. Make AbstractEdge have a member protected Set backingSet; which is initialized with different Set implementations by the subclasses. This is implies that you don't need AbstractSetView and its subclasses.
Otherwise, member protected Set backingSet; can be located in AbstractSetView.
The two answers given so far both offer a solution and advice for the Set case. However, a pattern you can use in this and other similar situations (for example, you are not extending a JRE class, but your own stuff) is to split the interface in a public and an inner protected one.
Your public interface, in this case, will be Set.
Your protected inner interface will be InternalSet, declared inside AbstractEdge, defining the removeInternal method. The method will be "public", but the interface does not need to be.
Then, the abstract super class should define a public method returning the public interface for use outside your subclasses, and a protected one returning the protected interface for internal use only.
Implementing subclasses can then implement a class, extending whatever Set you need, and also implementing the protected class, and return an instance of it from both methods.
The choice between composition or inheriting from JRE classes is all yours.

#MustOverride annotation?

In .NET, one can specify a "mustoverride" attribute to a method in a particular superclass to ensure that subclasses override that particular method.
I was wondering whether anybody has a custom java annotation that could achieve the same effect. Essentially what i want is to push for subclasses to override a method in a superclass that itself has some logic that must be run-through. I dont want to use abstract methods or interfaces, because i want some common functionality to be run in the super method, but more-or-less produce a compiler warning/error denoting that derivative classes should override a given method.
I don't quite see why you would not want to use abstract modifier -- this is intended for forcing implementation by sub-class, and only need to be used for some methods, not all. Or maybe you are thinking of C++ style "pure abstract" classes?
But one other thing that many Java developers are not aware of is that it is also possible to override non-abstract methods and declare them abstract; like:
public abstract String toString(); // force re-definition
so that even though java.lang.Object already defines an implementation, you can force sub-classes to define it again.
Ignoring abstract methods, there is no such facility in Java. Perhaps its possible to create a compile-time annotation to force that behaviour (and I'm not convinced it is) but that's it.
The real kicker is "override a method in a superclass that itself has some logic that must be run through". If you override a method, the superclass's method won't be called unless you explicitly call it.
In these sort of situations I've tended to do something like:
abstract public class Worker implements Runnable {
#Override
public final void run() {
beforeWork();
doWork();
afterWork();
}
protected void beforeWork() { }
protected void afterWork() { }
abstract protected void doWork();
}
to force a particular logic structure over an interface's method. You could use this, for example, to count invocations without having to worry about whether the user calls super.run(), etc.
... and if declaring a base class abstract is not an option you can always throw an UnsupportedOperationException
class BaseClass {
void mustOverride() {
throw new UnsupportedOperationException("Must implement");
}
}
But this is not a compile-time check of course...
I'm not sure which attribute you're thinking about in .NET.
In VB you can apply the MustOverride modifier to a method, but that's just the equivalent to making the method abstract in Java. You don't need an attribute/annotation, as the concept is built into the languages. It's more than just applying metadata - there's also the crucial difference that an abstract method doesn't include any implementation itself.
If you do think there's such an attribute, please could you say which one you mean?
Android has a new annotation out as announced in the Google I/O 2015:
#callSuper
More details here:
http://tools.android.com/tech-docs/support-annotations
If you need some default behaviour, but for some reason it should not be used by specializations, like a implementation of a logic in a non abstract Adapter class just for easy of prototyping but which should not be used in production for instance, you could encapsulate that logic and log a warning that it is being used, without actually having to run it.
The base class constructor could check if the variable holding the logic points to the default one. (writing in very abstract terms as I think it should work on any language)
It would be something like this (uncompiled, untested and incomplete) Java (up to 7) example:
public interface SomeLogic {
void execute();
}
public class BaseClass {
//...private stuff and the logging framework of your preference...
private static final SomeLogic MUST_OVERRIDE = new SomeLogic() {
public void execute() {
//do some default naive stuff
}
};
protected SomeLogic getLogic() { return MUST_OVERRIDE; }
//the method that probably would be marked as MustOverride if the option existed in the language, maybe with another name as this exists in VB but with the same objective as the abstract keyword in Java
public void executeLogic() {
getLogic().execute();
}
public BaseClass() {
if (getLogic() == MUST_OVERRIDE) {
log.warn("Using default logic for the important SomeLogic.execute method, but it is not intended for production. Please override the getLogic to return a proper implementation ASAP");
}
}
}
public GoodSpecialization extends BaseClass {
public SomeLogic getLogic() {
//returns a proper implementation to do whatever was specified for the execute method
}
//do some other specialized stuff...
}
public BadSpecialization extends BaseClass {
//do lots of specialized stuff but doesn't override getLogic...
}
Some things could be different depending on the requirements, and clearly simpler, especially for languages with lambda expressions, but the basic idea would be the same.
Without the thing built in, there is always some way to emulate it, in this example you would get a runtime warning in a log file with a home-made-pattern-like-solution, that only your needs should point if it is enough or a more hardcore bytecode manipulation, ide plugin development or whatever wizardry is needed.
I've been thinking about this.
While I don't know of any way to require it with a compile error, you might try writing a custom PMD rule to raise a red-flag if your forgot to override.
There are already loads of PMD rules that do things like reminding you to implement HhashCode if you choose to override equals. Perhaps something could be done like that.
I've never done this before, so I'm not the one to write a tutorial, but a good place to start would be this link http://techtraits.com/programming/2011/11/05/custom-pmd-rules-using-xpath/ In this example, he basically creates a little warning if you decide to use a wildcard in an import package. Use it as a starting point to explore how PMD can analyze your source code, visit each member of a hierarchy, and identify where you forgot to implement a specific method.
Annotations are also a possibility, but you'd have to figure out your own way to implement the navigation through the class path. I believe PMD already handles this. Additionally, PMD has some really good integration with IDEs.
https://pmd.github.io/

java traits or mixins pattern?

Is there a way to emulate mixins or traits in java? basically, I need a way to do multiple inheritance so I can add common business logic to several classes
Not the way you want to do it. Effective Java recommends that you "Favor composition over inheritance". Meaning you move the common logic to other classes and delegate. This is how you get around the lack of multiple inheritance in java.
I would encapsulate all of the business logic into a new class BusinessLogic and have each class that needs BusinessLogic make calls to the class. If you need a single rooted heirarchy for your classes that make calls to BusinessLogic, you'll have to create an interface as well (BusinessLogicInterface?)
In pseudo-code:
interface BusinessLogicInterace
{
void method1();
void method2();
}
class BusinessLogic implements BusinessLogicInterface
{
void method1() { ... }
void method2() { ... }
}
class User
extends OtherClass
implements BusinessLogicInterface
{
BusinessLogic logic = new BusinessLogic();
#Override
void method1() { logic.method1(); }
#Override
void method2() { logic.method2(); }
}
This isn't the prettiest implementation to work around a lack of multiple inheritance and it becomes quite cumbersome when the interface has a lot of methods. Most likely, you'll want to try and redesign your code to avoid needing mixins.
Is the object-purist stirring in you today?
Think you could do with a little composite oriented programming?
Then you, sir, are looking for Apache Polygene (formerly named Qi4J, then it renamed to Zest and/or Apache-Zest) ;)
Update 2022; It's discontinued currently, but useful anyway.
Java's answer to multiple inheritance is the ability to implement multiple interfaces. Of course, this means you'll get the method declarations, but not the logic.
You could try emulating mixins by composition: your Java class could define member variables that represent other classes that perform some common business logic.
In designing Java classes, I have not found the lack of C++ style multiple inheritance to inhibit the design of my architecture. You will find a way to achieve what you want to do.
QI4J allows you to use mixins
You can exploit the fact that interfaces allow nested classes (automatically public static) to keep the default implementation of the interface methods encapsulated within the interface itself. I.e. move the BusinessLogic class of Alex B's example inside the interface.
This is similar to the way Scala generates the JVM code for traits as explained here How are Scala traits compiled into Java bytecode?
When doing this the example becomes:
interface BusinessLogicInterface {
void method0();
class DefaultImpl {
private DefaultImpl() {
}
public static void method1(BusinessLogicInterface self) { ... }
public static void method2(BusinessLogicInterface self) { ... }
}
void method1();
void method2();
}
class User extends OtherClass implements BusinessLogicInterface {
#Override
void method0() { ... }
#Override
void method1() { BusinessLogic.defaultImpl.method1(this); }
#Override
void method2() { BusinessLogic.defaultImpl.method2(this); }
}
Note that we pass an object of the interface type as the "self" parameter. This means the business logic can use other abstract methods (method0). This can be very useful for creating a trait with abstract methods that are all orthogonal to each other and utility "extension" methods that may be implemented in terms of these orthogonal methods.
The drawback is that each interface must copy/paste the boilerplate delegation code. Another often used pattern in Java without this drawback (but with less cohesion and less OO way to call the methods) is to create a class with the plural name as the interface containing the static methods, this is used in the Collections utility class.
As of Java-8, default interface methods were added. This, together with multiple inheritance of interfaces in Java should allow some sort of mixin. Clearly the interfaces have to operate independently. So, there will be significant limitations.
Implementing simple mixin/traits support in java using CGLib/javassit is quite easy.
You can take a look for instance here for small example.
More complete, ready to use solution might be found: here

Java: Basic OOP Question

I have written a program with both a Advanced Mode and a Beginner Mode to allow the user to get the hang of my program before it is actually used. The Advanced Mode is almost identical to the Beginner Mode apart from one or two methods needing to be replaced by another, so I have decided to create a general Mode class for both Advanced Mode and Beginner Mode classes to use instead of just coping code: Here is the class structure if my explanation isn't very clear:
GUI Class
General Mode Class
Beginner Mode
Advanced Mode
Let's say that the General Mode class has the following code:
public class GeneralMode {
private int range;
private String id;
public GeneralMode() {
}
public int getRange() {
return range;
}
public String getID() {
return id;
}
public void doStuff() {
}
}
The GeneralMode class is where all the work gets done for the program. Now, I would like to make it so that the Advanced Mode class can take the input from the GUI class and use it in the same way as the GeneralMode class does.
Thank you for all your help!
Make 'GeneralMode' class, an abstract class, with abstract methods that have to be implemented by the concrete 'advanced' and 'beginner' classes.
The functionality that both modes have in common, can be implemented in the 'GeneralMode' class.
Then, in your GUI class, instantiate the correct concrete class, and put it in a 'GeneralMode' variable. Then, you can use it without you having to know whether your program is running in beginner mode or in advanced mode.
pseudocode:
GeneralMode mode = (UseAdvancedMode == true)? new AdvancedMode() : new BeginnerMode();
making the GeneralMode an abstract class definitely is the way to go to get the polimorphic behavior straight (as correctly explained by Frederik Gheysels).
one other important OO paradigm is to
favor composition over inheritance (Item 14, 'Effective Java' by Josh Bloch)
if your bulleted list represents your current inheritance hierarchy (ignore my comment if it doesn't...), i would strongly encourage you to change it so that your GUI Class is composed of a mode (rather than the mode being an extension of it -- the classical "is a" vs "has a" question). extracting whatever GUI settings into a parameter object which you will then pass to the modes to do their work would reduce the coupling even further.
Just to add to Frederik's answer, GeneralMode could also be an interface with BeginnerMode and AdvancedMode implementing this interface.
Use an abstract class if you want to share logic across all subclasses, if all classes will have the same implementation of getId and any other methods that will be the same.
If you want to leave the implementation of these methods up to the implementing class, then use an interface.
Another possibility is to use the Strategy Pattern. I'd prefer that one in your case, because I see more flexibility e.g. when changing the mode during run time. In that case you won't need to change your whole model instance (The Mode-Object), but only it's behaviour by loading a different Strategy. So you won't lose the state of your context by switching the mode.
public class GeneralContext //was GeneralMode in your Code-Example
{
...
public void doStuff()
{
myMode.doStuff()
}
public void changeStrategy(int mode)
{
switch(mode)
{
case EXPERT_MODE: myMode= new ExpertMode(); break;
....
default: throw NoSuchMode();
}
}
....
private interface Mode
{
void doStuff();
}
private class ExpertMode implements Mode
{
void doStuff()
{
....
}
}
private class BeginnerMode implements Mode
{
void doStuff()
{
....
}
}
}
Further reading: GoF-Book (see wikipedia), Pages 315 ff.
You're on the right way. You just need to modify the doStuff() method to take the input parameters you need from the GUI. Then the GUI can call this method over the mode object it has, and pass it the appropriate parameters.

Categories

Resources