I want to have a type hierarchy where only Foo objects are in control of the creation of Bar objects. E.g:
public abstract class Foo<F extends Foo<F>> {
public abstract Bar<F> makeBar();
}
public abstract class Bar<F extends Foo<F>> {}
Now a subclass of Foo could implement a subclass of Bar and give it back:
public class FooImpl extends Foo<FooImpl> {
private static class BarImpl extends Bar<FooImpl> {}
#Override
public Bar<FooImpl> makeBar() { return new BarImpl(); }
}
However that does still allow the creation of Bars elsewhere:
public class FakeBar extends Bar<FooImpl> {}
How can I restrict Bar<FooImpl> (using only the type system, not runtime checks) in a way that it must be created by an instance of FooImpl, and cannot be created in any other place?
This isn't something the type system can (or should) do. You want access restrictions, use Java's access modifiers. But I don't think those can implement your very specific and unusual requirements either.
Actually, I don't think they can be implemented at all: you want a class to be publically visible and non-final, yet allow the ability to call its constructors and to extend it only to a specific class and its subclasses?
Sorry, no can do. What would be the point anyway?
That doesn't work (with the limitation: type system only, no runtime checks). We can either disallow subclassing in general (final class) or allow it. If a (public) class is not final, any other class may subclass.
You could try playing with annotations - like inventing an annotation, that lists allowed classname, but this depends on processing the annotations.
Example:
#AllowedSubclasses(classnames="com.example.FooBar; *.AnyFooBar; com.example.foobars.*")
public abstract class Bar<F extends Foo<F>> {}
The annotation processor then would throw an error, if any other class subclasses this annotated class.
What about a mixed approach: annotate your internal methods with "HANDS OFF" in the javaDoc and document, that any violation will result in runtime exceptions. After the method has been called, you can verify within the method, if the caller is an instance of one of the classes, that are allowed to use this feature.
Well instead of relying on generics etc, a simpler way to accomplish this is to enforce that you need an instance of Foo to create a Bar
public Bar(Foo foo){...}
This way, no one can create a bar independently of Foo. This couples the 2 classes, and indicates to users of this fact as well. There are other ways to accomplish this as well... this is just one example
You can make makeBar a concrete method which calls a protected abstract makeBar0 which does the actual creation. makeBar() can take the result and check it the object any way you wish.
public abstract class Foo<F extends Foo<F>> {
public Bar<F> makeBar() {
Bar<F> bar = makeBar0();
// check bar
return bar;
}
}
If you prefer you could add a check on the creation of Foo which may be more performance. i.e. check the return type of makeBar0();
Related
I have a co worker who need a method to be available to two classes.
He decided to create a new interface to be implemented by those classes.
The interface has one method
default doThis(String parameter)
It does not have any other interface methods, there is no indication that other methods would be added to this interface.
I feel this is an incorrect usage of the interface and it should be done in a different way. I.e perhaps a class which has the method allowing other classes to consume this by using the object.
Does anyone with experience on this have any opinions to share?
I can update with more clarification based on your comments.
Update:
Here is the code and the question remains:
is this a valid use of the default method or should this common logic have been done in another way like a Utilities class which does the saving to preferences ?
Interface:
public interface LogInCookie {
default void mapCookiesToPreferences(String cookie) {
if (cookie.contains(MiscConstants.HEADER_KEY_REFRESH)) {
String refreshToken = cookie.replace(MiscConstants.HEADER_KEY_REFRESH, StringUtils.EMPTY);
SharedPrefUtils.addPreference(SharedPrefConstants.REFRESH_TOKEN, refreshToken);
}
}
}
public class HDAccountActivity extends AbstractActivity implements LogInCookie {
private void mapCookies(List<String> mValue) {
LogInCookie.super.mapCookiesToPreferences(mValue); //ekh!
}
}
public class BaseSplashPage extends AppCompatActivity implements DialogClickedCallBack, LogInCookie {
//method which uses this
private void mapCookiesToPreferences(List<String> headers) {
int firstItemInHeader = 0;
for (String header : headers) {
String mValue = header.substring(firstItemInHeader,header.indexOf(MiscConstants.SEMICOLON));
LogInCookie.super.mapCookiesToPreferences(mValue); //ekh!
}
}
}
A default method in an interface, which doesn’t define other methods, can’t do much useful things with the instance of the implementing class. It can only use methods inherited from java.lang.Object, which are unlikely to carry semantics associated with the interface.
If the code doesn’t use instance methods on this at all, in other words, is entirely independent from the this instance, you should make it static, change the containing class to a non-instantiable class type, i.e.
final class SomeUtilClass {
static void doThis(String parameter) {
// ...
}
private SomeUtilClass() {} //no instances
}
and use import static packageof.SomeUtilClass.doThis; in the classes using this method.
That way, all these classes can invoke the method like doThis(…) without a qualifying type name, without needing a misleading type hierarchy.
When the method actually uses the this instance, which, as said, can only be in terms of methods inherited from java.lang.Object, the type inheritance might be justified. Since this is rather unlikely, you might still consider the type hierarchy to be misleading and rewrite the code to
final class SomeUtilClass {
static void doThis(Object firstParameter, String parameter) {
// ...
}
private SomeUtilClass() {} //no instances
}
using firstParameter instead of this, which can be invoke like doThis(this, …).
Ideally you would put that method doThis() in an abstract class that both classes extend. However if you need to achieve multiple inheritance then using an interface here is fine.
A class with a static method doThis() that you can call staticly would also work.
It all depends on how you have your project organized imo.
In java 8 , default keyword in interface was introduced for those cases where if any set of apis had long inheritance hierarchy and we wanted to introduce a method that should be available in all of the lower lying classes.
So for ex. in Java 8 stream() method was introduced in the Collection interface as a default method and it ended up being available in all of the underlying classes.
As far as your case in considered , if I go by your words then if yours is a new development then you should be using interface -> abstract class -> actual implementing class.
Only if yours was an older development setup and you already had classes implementing from an interface , that could have been an ideal scenario for using default method in your interface.
A default method in an interface
*)can have a default implementation
*)which can overridden by the implementing class
yes its a correct usage since JAVA8.
we can have default method in an interface as well as a abstract method
I've been trying to design a set of classes to model a classic RPG. I've found myself confused on how to solve this one issue, however: how do I force the use of character-type (e.g. Tank, Healer, DPS) specific spells/equipment, etc. in an abstract class. The example below better articulates what I mean.
I've got an abstract PlayableCharacter class which all character-types inherit from:
public abstract class PlayableCharacter {
private Set<Spell> mSpells;
...
public void addSpell(Spell spell) {
mSpells.add(spell);
}
}
For example:
public class Healer extends PlayableCharacter { ... }
public class Tank extends PlayableCharacter { ... }
Note the Set of Spell in the abstract class. I would like it if each subclass of PlayableCharacter could use its addSpell method but with the restriction that the type of Spell correspond to the PlayableCharacter subtype.
For example I have these Spell classes:
public abstract class Spell { ... }
public class HealerSpell extends Spell { ... }
public class TankSpell extends Spell { ... }
I only want Healers to use HealerSpells and Tanks to use TankSpells, etc. For example:
PlayableCharacter tank = new Tank();
tank.addSpell(new TankSpell()); // This is fine
tank.addSpell(new HealerSpell()); // I want to prevent this!
I thought of giving each subclass of PlayableCharacter it's own Set of subclass-specific Spells, but that creates a lot of code duplication.
I also tried making PlayableCharacter.addSpell marked as protected, then each subclass would have to implement an interface like this:
public interface Spellable<T extends Spell> { void addClassSpell(T spell); }
and each subclass that implements it would call super.addSpell(spell); but that lead to more code duplication and nothing was forcing those implementations to do the super call.
Is my strategy fundamentally flawed in some way? Any advice? I feel like this issue will keep getting worse as I add more character-type-specific equipment, traits, and so on.
I wouldn't do it that way (via type inheritance). It would be better to add characteristics to a Spell itself because it's a spell, which can be cast by a certain character only. Also, a specific spell can be cast to a certain character type only. These rules belong to a spell, not to a character.
Spell rules can be checked in a runtime by a separate class or by a Spell class itself inside a cast() method or another one.
so far what you have is good
the rest of the stuff, think more strategy pattern than super call
so abstract class can have algorithm that does step1, step2, step3 with possible parent implementation
child classes can override it, but only override parts that is different
when you call algorithm, it performs all steps
Steps themselves could be different class that has logic, if everything becomes too big
maybe have each subclass of playable character store the class (or classes) of subspells that are allowed. then do an if(spell instance of allowedSpell) ...
I have a structure like follows
Interface A
Interface B extends Interface A
abstract Class C implements Interface B
now concrete Class D extends Class C
Now I am using Interface B in a different class and returning the concrete class D object.
Interface B contains getters and setters and modifying methods.
What I want is that I want to take out all the getters from Interface B somehow and put them in a separate interface so that when I return a concrete object I don't have access to the setters and modifiers of Interface B. But I want to use Interface B as my return object with this newly built read-only concrete object. I am not get any idea about how to achieve this?
One way to achieve this would be to create a read-only wrapper object which implements interface B, propagates the getters to the wrapped object and raises an exception (like IllegalAccessEXception or InvalidStateException) from within the setters and modifiers.
It sounds like you are referring to the Proxy design pattern : http://en.wikipedia.org/wiki/Proxy_pattern.
In your case, you want Interface B to support getting/setting of certain fields, but you want it to provide a specific proxy for setting and getting those fields, rather then directly editing them.
This is rarely done, but you can create an inner-interface, which is specific and local to the interface you want to support. For example :
public interface Proxiable {
public static interface Proxy
{
}
public ProxySub getProxy();
}
Thus, your interface is defining a proxy interface - and anyone who extends your interface will have to provision a Proxy provider.
However, unless you have a REALLY good reason for doing this, you might be overabstracting. Interfaces are generic enough that it is usually sufficient to leave the details of HOW methods are implemented to subclasses, rather than forcing this superstructure at the interface level.
Elaborating on the excellent suggestion by #rsp :
Create a "read-only" interface
public interface MyInterfaceRO {
public int getFoo();
public String getBar();
// etc...
}
Create the "read-write" interface, corresponding to your B
public interface MyInterfaceRW extends MyInterfaceRO {
public void setFoo(int foo);
public void setBar(String bar);
// ...
}
IMO, the simplest way to do what you want (prevent modification) is to just return MyInterfaceRO. The caller (unless they do a cast) will have no ability to call setFoo(), in fact, in their IDE they won't even see .setFoo() as an option.
I don't understand why you really want to return a type B (my RW above), but, if you do, you are stuck with the caller having the ability to see and call setFoo(). Probably your best bet would be to follow the precedent set in java's Collections and throw an UnsupportedOperationException. As a convenience, you could offer a method
public boolean isModifiable();
but you can't force the caller to use and respect that.
Right now I the following:
1) A java interface.
2) A concrete java class that does not implement the aforementioned interface, but does contain a method signature matching every one of the methods defined in the interface.
Since I am unable to change the implementation of item 2, I would like to know if it is possible to make a method that accepts an instance of item 1 as an argument accept item 2 without a class cast exception.
It feels like the various weaving/coercion/AOP mechanics in Spring should make this possible, but I don't know how to do it.
Is there a way to make this happen?
Can you force a java object into implementing an interface at runtime?
Yes, using dynamic proxies or byte-code rewriting. However, to me it seems like you're looking for the Adapter pattern.
You can't make the object itself implement the interface, but you could use something like Proxy to create an object which implements the interface and uses reflection to call the appropriate member on the original object.
Of course, if it's just the one interface type and the one concrete type, you could easily write such a wrapper without using Proxy:
public class BarWrapper implements Foo
{
private final Bar bar;
public BarWrapper(Bar bar)
{
this.bar = bar;
}
public int someMethodInFoo()
{
return bar.someMethodInFoo();
}
// etc
}
This should be solvable with an adapter.
Have an other class defined that implements your interface and delegates to the real object:
class YourAdapter implements YourInterface {
private final YourClass realObject;
public YourAdapter(YourClass realObject) {
this.realObject = realObject;
}
#Override
public methodFromInterface() {
// you said the class has the same method signatures although it doesn't
// implement the interface, so this should work fine:
realObject.methodFromInterface();
}
// .......
}
Now, given a method that expects YourInterface and an object of type YourClass:
void someMethod(YourInterface param) {}
void test() {
YourClass object = getFromSomewhere();
someMethod( YourAdapter(object) );
}
You can probably do what you want with Javassist, either by modifying the class's bytecode or creating a wrapper/proxy class.
Basically there are two ways:
a) write a decorator around your Object that implements the interface and delegates to your object (this can be done either by using proxies or by writing a simple adapter class)
b) change the byte code. Spring AOP is not powerful enough to do that, but the AspectJ compiler is. It's a one-liner:
declare parents: YourClass implements YourInterface;
Since you don't have access to the class source you will have to either use Load Time Weaving or weave the library jar. All of this is explained well in AspectJ in Action by Ramnivas Laddad
Are there some practical programming situations for someone to declare a class abstract when all the methods in it are concrete?
Well you could be using a template method pattern where there are multiple override points that all have default implementations but where the combined default implementations by themselves are not legal - any functional implementation must subclass.
(And yes, I dislike the template method pattern ;))
An abstract class is a class that is declared abstract - it may or may not include abstract methods. They cannot be instantiated so if you have an abstract class with concrete methods then it can be subclassed and the subclass can then be instantiated.
Immagine an interface whose declared methods usually show the same default behavior when implemented. When writing a class that needs to support the interface you have to define said default behavior over and over.
To facilitate implementation of your concrete classes you might want to provide an abstract class providing default behavior for each method. To support the interface in a concrete class you can derive from the abstract class and override methods if they deviate from the standard behavior. That way you'll avoid the repeated implementation of the same (redundant) default behavior.
Another possible use case is a decorator which delegates all calls to the wrapped instance. A concrete decorator implementation can override only those methods where functionality is added:
public interface Foo {
public void bar();
}
public abstract class FooDecorator implements Foo {
private final Foo wrapped;
public FooDecorator(Foo wrapped) { this.wrapped = wrapped; }
public void bar() { wrapped.bar(); }
}
public class TracingFoo extends FooDecorator {
//Omitting constructor code...
public void bar() {
log("Entering bar()");
super.bar();
log("Exiting bar()");
}
}
Although I don't really see the necessarity to declare FooDecorator as abstract (non-abstract example: HttpServletRequestWrapper).
Previous answers already hit the main issues, but there's a minor detail that might be worth mentioning.
You could have a factory that returns instances of (hidden) subclasses of the abstract class. The abstract class defines the contract on the resulting object, as well as providing default implementations, but the fact that the class is abstract both keeps it from being instantiated directly and also signals the fact that the identity of the "real" implementation class is not published.
Wondering why no one has pointed to the Practical Example of MouseAdapter:
http://docs.oracle.com/javase/6/docs/api/java/awt/event/MouseAdapter.html
An abstract adapter class for receiving mouse events. The methods in
this class are empty. This class exists as convenience for creating
listener objects.
Nice question :)
One thing is for sure ... this is certainly possible. The template suggestion by krosenvold is one good reason for doing this.
I just want to say that a class must not be declared abstract just for preventing it's instantiation.
This is referred in the Java Language Specification Section 8.1.1.1
When you have an important class but the system cannot create an instance fo this class, because
this class is parent of a lot of classes of the system;
this has a lot of responsability (methods used by a lot of class) for domain's requires;
this class not represents a concrete object;
Servlet Example:
All methods are concrete,
but the base class is useless by itself:
DeleteAuthor.java
Abstract class with concrete doGet method.
doGet calls file pointed to in protected string sql_path.
sql_path is null.
DeleteAuthorKeepBook.java
extends abstract class DeleteAuthor
sets sql_path to delete_author_KEEP_BOOK.sql
DeleteAuthorBurnBook.java
extends abstract class DeleteAuthor
sets sql_path to delete_author_BURN_BOOK.sql