I want to create a private Interface in Class A and have it implemented by Class B. My intention is to have a way for Class A to call a method set on class B that NO ONE else can call. They are in separate file in separate packages. Anyone have any ideas?
The best you can achieve is to give the interface package level visibility and move Class A and B into the same package.
This doesn't stop someone adding another class into the same package in the future, thus giving it access to the interface.
short answer is redesign your class structure.
But if you really need to, consider to use reflex feature in java. and you can inject the method although not recommended.
Disclaimer: not a Java programmer.
But if you want to leverage a type system to get compile-time errors... there are often tricks by introducing a new data type as a sort of "access token" or "dummy parameter". Make it hard to get ahold of a value of that type, but require a value of that type as a parameter in the interface.
Yet introducing a hoop like that winds up being about as contrived as renaming your methods alarming things like DoFooActionOnClassB_ButDontCallUnlessYouAreClassA. I think one usually finds that in a good design, this "dummy type" isn't a dummy type at all... but a capture of the context and state that you should have had in the first place.
I understand that you want to have methods on class B which can only be called from class A. One way would be deferring the real check until runtime but let the compiler make it hard to do the wrong thing. So you could try using a secret which only class A can have in order to protect the method in class B.
public class A {
private static final PrivateA PROOF = new PrivateA();
public static class PrivateA {
private PrivateA() { }
// only A can extend PrivateA
}
public static void main(String[] args) {
new B().methodForAOnly(PROOF, "A");
}
}
Here A's PrivateA is a type which only A can instantiate or extend, and B knows about that...
public class B {
public void methodForAOnly(PrivateA proof, String param) {
if (proof == null) throw new NullPointerException();
// do something
System.out.println(param);
}
}
Related
As mentioned below (to remark it as I might have explained myself badly):
I want to understand the principle behind this issue so that I can apply that knowledge to the real problem.
ISSUE START
I am working in a system intended to be an abstract library to be used by many subsystems. The idea is to have an standard behaviour extensible by implementations.
My problem is that java compiler is not able to inferr method parameter type, even though it makes no sense since the boundaries are well set on every related generic class/method.
Below there is an example, the minimum example to reproduce the problem. I am aware it looks a bit silly in this example, but that is because of the simplification:
public class Test {
public static void main(String[] args) {
Gen<? extends Base> gen = new HijaGen();
gen.applyTo(Hija.EXAMPLE);
}
private interface Base {
String getName();
}
private enum Hija implements Base {
EXAMPLE;
#Override
public String getName() {
return this.name();
}
}
private interface Gen<T extends Base> {
boolean applyTo(T base);
}
private static class HijaGen implements Gen<Hija> {
#Override
public boolean applyTo(Hija base) {
return false;
}
}
}
Basically it says that applyTo expects a subclass of Base and Hija is not valid, which from my perspective makes no sense.
Thanks in advance.
EDIT:
This code is for a library, so that the solution could not be specifying the type since then it could not be extensible through particular implementations.
I am already aware that if I specify the generic type instead of throwing a type wildcard it will perfectly work. But my question is how is it possible that even though Hija subclasses Base, and method firm requires a subclass of Base it will never compile...
I want to understand the principle behind this issue so that I can apply that knowledge to the real problem.
A Gen<? extends Base> is a Gen of something which extends Base. It applies to some specific type of Base but we do not know which. In practice, this means you will never be able to call applyTo on a variable with type Gen<? extends Base>, except by passing null.
Change your code to
Gen<Hija> gen = new HijaGen();
gen.applyTo(Hija.EXAMPLE);
I suspect you'll probably say you can't do that, because your code is just an example, and the above is not possible in the real code. In which case you will need to give a better example
I think there is a similar problem explained in the docs here and the problem that they propose is to make a helper (or wrapper) to clarify the types. So I guess you can try adding this function:
private static <T extends Base> boolean applyTo(Gen<T> gen, T base){
return gen.applyTo(base);
}
And change the main function as follows:
public static void main(String[] args) {
boolean b = applyTo(new HijaGen(), Hija.EXAMPLE);
}
On the lines of what Carlos has mentioned, there is one more way to resolve this. It can be used if you are sure of the suppliers of the implementation of Gen<T>.
Here, instead of the helper to call applyTo(), we define a factory method to create the instance of the Gen implementation and cast it to Gen<Base>, which in my opinion is safe for all practical purposes. Note that the factory method get() need not be static. The rest of the code remains unchanged from your sample.
public static void main( String[] args ){
Gen<Base> gen = (Gen<Base>) get();
gen.applyTo( Hija.EXAMPLE );
}
static Gen<? extends Base> get(){
/* Create the instance of the Gen interface implementation here. */
return new HijaGen();
}
Explanation
Gen<? extends Base> expects to refer to an instance of an implementation of Gen that uses a type that is either Base or an sub-type of it. Since a "sub-type" can be from one of many possible hierarchies from Base downward (as shown in the picture below), it cannot be sure that the parameter passed to applyTo() method is of the same child hierarchy path and not just a 'relative' with the same ancestral parent Base. That is why it won't allow a call to applyTo() with its reference being of Gen<? extends Base> for a parameter of with reference as Base.
However, when the reference is Gen<Base>, it knows that applyTo() will accept any parameter that is a child type of Base. And hence, it stops worrying about type mismatch.
I have tried to show what I mean by different child hierarchy paths. It is like the case of a family tree.
I need to add one optional method in existing abstract class that is extended by more than 50 classes:
public abstract class Animal{...}
This method is not used by all those classes, but in the future it probably will.
The structure of one of my classes is:
public class Dog extends Animal {...}
The cleanest way is using abstract method but it obliges me to change all existing classes.
The workaround is to create "empty" method in abstract class:
public String getString(Map<String, Object> params){
return "";
}
and then override it when I need in classes that extend abstract class.
Is there any better solution?
Having an "empty" method is fine. But in order to be sure, that it will be implemented where it is really needed, consider throwing an exception by default from this method:
throw new UnsupportedOperationException();
A similar approach is used in java.util.AbstractList class:
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
I can't help feeling like you have some architectural/design issues here, but without knowing more, I can't say for sure. If 50 classes are going to inherit from Animal, but not all of them are going to use this method, then I'm wondering if they should really inherit from one common class. Perhaps you need further levels of sub-classing... think Kingdom->Phylum->Sub-Phylum. But my gut says that's still not the right answer for you.
Step back - what are you trying to accomplish? If you're going to implement this function on these classes in the future, then you must also be changing your code to know to use/expect this. The point of inheritance is to allow code to refer to an object's expected common behavior without knowing what type of object it's referencing. In your getString() example, you might have a function as such:
public string SendMessage(Animal someAnimal) {
string message = someAnimal.getString();
// Send the message
}
You can pass it a dog, a cat, a platypus - whatever. The function doesn't care, because it can query the message from its base class.
So when you say you'll have animals that don't implement this message... that implies you'll have logic that ensures only cats and dogs will call this function, and that a platypus is handled differently (or not at all). That kind of defeats the point of inheritance.
A more modern approach would be to use interfaces to establish a "has a" relationship instead of an "is a" relationship. A plane might have an IEngine member, but the specific type of engine can be set at run-time, either by the plane class itself, or by the app if the member is writeable.
public interface IEngine {
string getStatus();
string getMileage();
}
public class Cessna {
public IEngine _engine;
public Cessna() {
_engine = new PropellerEngine();
}
}
You could also inherit directly from that interface... Animals that don't implement IAnimalMessage wouldn't implement that function. Animals that do would be required to. The downside is that each animal will have to have its own implementation, but since your base class currently has an abstract function with no body, I'm assuming that's a non-issue. With this approach, you can determine if the object implements the interface as such:
IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;
// If your playtpus doesn't implement IAnimalMessage,
// animalMessage will be null.
if (null != animalMessage) {
string message = animalMessage.getString();
}
public interface IAnimalMessage {
string getMessage();
}
public class Platypus : IAnimalMessage {
// Add this implementation when Platypus implements IAnimalMessage...
// Not needed before then
public string getMessage() {
return "I'm a cowboy, howdy, howdy, howdy!";
}
}
That's probably the closest to what you're asking for I can suggest... classes that don't need the message won't implement that interface until they do, but the code can easily check if the interface is implemented and act accordingly.
I can offer more helpful/specific thoughts, but I'd need to understand the problem you're trying to solve better.
Let's say you have some Java code as follows:
public class Base{
public void m(int x){
// code
}
}
and then a subclass Derived, which extends Base as follows:
public class Derived extends Base{
public void m(int x){ //this is overriding
// code
}
public void m(double x){ //this is overloading
// code
}
}
and then you have some declarations as follows:
Base b = new Base();
Base d = new Derived();
Derived e = new Derived();
b.m(5); //works
d.m(6); //works
d.m(7.0); //does not compile
e.m(8.0); //works
For the one that does not compile, I understand that you are passing in a double into Base's version of the m method, but what I do not understand is... what is the point of ever having a declaration like "Base b = new Derived();" ?
It seems like a good way to run into all kinds of casting problems, and if you want to use a Derived object, why not just go for a declaration like for "e"?
Also, I'm a bit confused as to the meaning of the word "type" as it is used in Java. The way I learned it earlier this summer was, every object has one class, which corresponds to the name of the class following "new" when you instantiate an object, but an object can have as many types as it wants. For example, "e" has type Base, Derived, (and Object ;) ) but its class is Derived. Is this correct?
Also, if Derived implemented an interface called CanDoMath (while still extending Base), is it correct to say that it has type "CanDoMath" as well as Base, Derived, and Object?
I often write functions in the following form:
public Collection<MyObject> foo() {}
public void bar(Collection<MyObject> stuff){}
I could just as easily have made it ArrayList in both instances, however what happens if I later decide to make the representation a Set? The answer is I have a lot of refactoring to do since I changed my method contract. However, if I leave it as Collection I can seamlessly change from ArrayList to HashSet at will. Using the example of ArrayList it has the following types:
Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess
There are a number of cases where confining yourself to a particular (sub)class is not desired, such as the case you have where e.m(8.0);. Suppose, for example, you have a method called move that moves an object in the coordinate graph of a program. However, at the time you write the method you may have both cartesian and radial graphs, handled by different classes.
If you rely on knowing what the sub-class is, you force yourself into a position wherein higher levels of code must know about lower levels of code, when really they just want to rely on the fact that a particular method with a particular signature exists. There are lots of good examples:
Wanting to apply a query to a database while being agnostic to how the connection is made.
Wanting to authenticate a user, without having to know ahead of time the strategy being used.
Wanting to encrypt information, without needing to rip out a bunch of code when a better encryption technique comes along.
In these situations, you simply want to ensure the object has a particular type, which guarantees that particular method signatures are available. In this way your example is contrived; you're asking why not just use a class that has a method wherein a double is the signature's parameter, instead of a class where that isn't available. (Simply put; you can't use a class that doesn't have the available method.)
There is another reason as well. Consider:
class Base {
public void Blah() {
//code
}
}
class Extended extends Base {
private int SuperSensitiveVariable;
public setSuperSensistiveVariable(int value) {
this.SuperSensistiveVariable = value;
}
public void Blah() {
//code
}
}
//elsewhere
Base b = new Extended();
Extended e = new Extended();
Note that in the b case, I do not have access to the method set() and thus can't muck up the super sensitive variable accidentally. I can only do that in the e case. This helps make sure those things are only done in the right place.
Your definition of type is good, as is your understanding of what types a particular object would have.
What is the point of having Base b = new Derived();?
The point of this is using polymorphism to change your implementation. For example, someone might do:
List<String> strings = new LinkedList<String>();
If they do some profiling and find that the most common operation on this list is inefficient for the type of list, they can swap it out for an ArrayList. In this way you get flexibility.
if you want to use a Derived object
If you need the methods on the derived object, then you would use the derived object. Have a look at the BufferedInputStream class - you use this not because of its internal implementation but because it wraps an InputStream and provides convenience methods.
Also, I'm a bit confused as to the meaning of the word "type" as it is used in Java.
It sounds like your teacher is referring to Interfaces and Classes as "types". This is a reasonable abstraction, as a class that implement an interface and extends a class can be referred to in 3 ways, i.e.
public class Foo extends AbstractFoo implements Comparable<Foo>
// Usage
Comparable<Foo> comparable = new Foo();
AbstractFoo abstractFoo = new Foo();
Foo foo = new Foo();
An example of the types being used in different contexts:
new ArrayList<Comparable>().Add(new Foo()); // Foo can be in a collection of Comparable
new ArrayList<AbstractFoo>().Add(new Foo()); // Also in an AbstractFoo collection
This is one of the classic problems on object oriented designs. When something like this happens, it usually means the design can be improved; there is almost always a somewhat elegant solution to these problems....
For example, why dont you pull the m that takes a double up into the base class?
With respect to your second question, an object can have more than one type, because Interfaces are also types, and classes can implement more than one interface.
I have a variable: Abstract a. It is a class that extends the Abstract class. However, I need to cast this Abstract variable into a more specific class variable that extends the Abstract class.
My situation: I have two classes, Class1 and Class2 that both extend the Abstract class with methods implemented in each one. I now have an Abstract class variable to work with. I do not know if it is Class1 or Class2, so I cannot simply do a (Class1) a or a (Class2) a (casting).
So how would I successfully cast this variable so that I can use the inner methods?
I was thinking along the lines of using a.getClass().getName() to determine how to cast it, but I am stuck from here on out.
Your new question appears to be asking how to dynamically cast a variable to an arbitrary type unknown at runtime. This is probably a duplicate of java: how can i do dynamic casting of a variable from one type to another? but to summarize, this is not (easily) possible, isn't recommended, and speaks to other issues in your code.
Think about it this way, what variable would you possibly be able to use to store your newly cast object? Imagine if we had a (child) cast operation in Java, that took a variable defined as a parent class, and cast it down to its child (e.g. List -> LinkedList):
public static void func(Abstract a){
???? var = (child)a;
// Do something with var?
}
Notice that 1) there's no way you could ever specify a type for var, since we don't know at runtime what type it will be; and 2) there's nothing we'd be able to do with var beyond the behavior defined in Abstract anyways, because the compiler can't predict which methods will be availible to var other than what's available to Abstract.
If you need to implement class-specific behavior, you should do so inside the class. Have an abstract method which each class has to implement, and which can do whatever you need them to do. Or, if you cannot ensure that, don't define a function that takes an Abstract as an argument; instead define however many functions that take Class1, Class2, etc. objects as parameters, like so:
Abstract method to require all child classes behave similarly
public abstract class Abstract{
/** Do the class-specific behavior you want to do currently in func */
public abstract void operation();
public static void func(Abstract a){
a.operation();
}
}
Functions only for classes that can actually handle what you want
public static void func(Class1 a){
// do something
}
public static void func(Class2 a){
// do something
}
Again, if neither of these options are viable for you (and of course, blocks of instanceof calls aren't acceptable) then I'd be willing to bet money there's something structural in the way you're using Java that's fundamentally incorrect. If you want to post a code sample of exactly what you're trying to accomplish by child-casting, perhaps we can shed some light as to what the issue is.
Leaving this here for posterity - OP's original question asked about creating new instances of an object cast as its abstract parent.
Pretty straightforward, get the object's class object, and create a new instance. For more complex constructors, see the Java documentation on creating new instances dynamically.
public class ClassVar
{
public static abstract class Abstract
{
}
public static class Class1 extends Abstract
{
}
public static class Class2 extends Abstract
{
}
/**
* Given an instance of a child of Abstract, returns a new instance
* of the same class
*/
public static Abstract newInstance(Abstract obj) throws InstantiationException, IllegalAccessException
{
return obj.getClass().newInstance();
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException
{
System.out.println(newInstance(new Class1()).getClass());
System.out.println(newInstance(new Class2()).getClass());
}
}
Result:
class ClassVar$Class1
class ClassVar$Class2
Basically you can use reflection by using
Class cl = ...
cl.newInstance()
The more 'expanded' answer you can find here
Since you edited your question again 3h ago at the time of writing here's my second answer to a problem I thought was solved. It's obvious nobody got what you're really asking for in the first place. Try to improve how you're asking questions.
However, the answer is simple:
From the point of view of object orientation you simply shouldn't have to (Liskov Substitution principle). Even if you have exact knowledge about exactly two possible instances, you should look for a better approach for the problem you are trying to model.
If you have to, determine the class name and check for equality or carry an extra identifier and compare that one. Implementation couldn't be simpler.
I have a lot of code that calls static methods on Foo like "Foo.method()". I have two different implementations of Foo and would like to use one or the other depending on the circumstances. In psuedocode:
File Foo1.java
class Foo1 implements Foo {
public static int method() {
return 0;
}
}
File Foo2.java
class Foo2 implements Foo {
public static int method() {
return 1;
}
}
File Main.java
if(shouldLoadFoo1()) {
Foo = loadClass("Foo1");
} else {
Foo = loadClass("Foo2");
}
Is this possible with Java metaprogramming? I can't quite wrap my head around all the dynamic class loading documentation. If not, what's the best way to do what I'm trying to do?
Essentially you have two classes with the same interface but different implementations,Wouldn't it be better to do it using an interface?
in your main class, depending on the circumstances you would construct your class with the appropriate instance.
FooInterface foo;
MainClass (FooInteface foo, other fields) {
this.foo = foo;
}
....
then just use foo from them on.
Another way is to use AspectJ, define a point cut on every Foo.method call, in in the advice for the point cut have your if (shouldLoadFoo1()) { Foo1.method()} etc ..
The typical approach to exchanging implementations is to use a non-static method and polymorphism, typically using dependency injection to tell the depedent code the implementation to use.
The next cleanest way is the singleton pattern, i.e. to declare:
public abstract class Foo {
protected abstract void doSomeMethod();
// populated at startup using whatever logic you desire
public static Foo instance;
public static void someMethod() {
instance.doSomeMethod();
}
}
The really hacky way to solve your problem would be what you ask for, i.e. to have two different class files for the same class, and decide at runtime which one to use. To do that, you would seperate your project into 4 different jar files:
loader.jar that determines the classpath to use and constructs the classloader for the actual application. The classes in loader.jar must not reference Foo.
foo1.jar that contains one implementation for Foo
foo2.jar that contains another implementation for Foo
common.jar that contains everything else
Loader.jar would then contain a bootstrap method like:
void bootstrap() {
URL commonUrl = // path to common.jar
URL fooUrl;
if (shouldUseFoo1()) {
fooUrl = // path to Foo1.jar
} else {
fooUrl = // path fo Foo2.jar
}
URL[] urls = {fooUrl, commonUrl};
ClassLoader loader = new UrlClassLoader(urls);
Class<?> mainClass = loader.loadClass("my.main");
mainClass.newInstance(); // start the app by invoking a constructor
}
I am not sure I fully understand the problem here (I see many has that issue), but let me try to help.
If your problem was coming down just to using appropriate function method(), you could create a utility function that depending on an instance of a given class will call appropriate method, e.g.
private static int getResultOfFoo(Foo foo)
{
int res = -1;
if(foo instanceof Foo1)
res = Foo1.method();
else res = Foo2.method();
return res;
}
Otherwise, I agree with Stephen C: "Well, see my answer then. That's the closest you are likely to get in Java."
What you have written doesn't make sense from a linguistic standpoint. Foo is an type, and a type is not a variable and cannot appear on the LHS of an assignment. You cannot treat a type as a value in Java ... the language doesn't allow it.
The closest that you can get to what you are trying to do is something like this:
Class fooClass;
if (loadFoo1) {
fooClass = Class.forName("some.pkg.Foo1");
} else {
fooClass = Class.forName("some.pkg.Foo2");
}
Foo foo = (Foo) fooClass.newInstance(); // using the no-args constructor
(I've left out the exception handling ...)
Note that fooClass will be an instance of the class Class which provides runtime handles that are used for performing operations reflectively. We are NOT actually assigning a type. We are assigning an object that "denotes" a type ... in a limited fashion.
HOWEVER ... if you don't need to use dynamic loading you should not use it. In other words, if the underlying problem that you are trying to solve is creating instances of classes that could be statically loaded, then it is better to use the factory pattern; see #andersoj's answer for example.
UPDATE
I just figured out what you are probably trying to do here. That is, you are trying to figure out a way to choose between different static methods (i.e. Foo1.method() and Foo2.method()) without explicitly naming the classes at the point where the call is made.
Again, what you are trying to do simply won't work in Java:
You cannot declare a static method in an interface.
You cannot call a static method in an implementation class via the interface.
Static method calls are not "dispatched" in Java. They are bound statically.
There is a way to do something roughly like this using reflection; e.g.
Class fooClass;
// Load one or other of the classes as above.
Method m = fooClass.getDeclaredMethod("method");
Integer res = (Integer) m.invoke(null);
(As before, I've left out the exception handling)
Once again you would be much better off doing this without resorting to dynamic loading and reflection. The simple approach would be to create a helper method like this in some utilities class:
public static int method() {
return useFoo1 ? Foo1.method() : Foo2.method();
}
Better still, do it the OO way: declare method in the Foo interface as a instance method, create a singleton or an injected instance of Foo1 or Foo2, and rely on polymorphism.
But the take away is that there is NO WAY to avoid changing all of the places in your codebase where method() is called ... if you want to be able to choose between Foo1.method and Foo2.method at runtime.
You can use a factory pattern to do this.
static Foo makeMeAFoo()
{
final Foo foo;
if(shouldLoadFoo1()) {
foo = new Foo1();
} else {
foo = new Foo2();
}
return foo;
}
Which is I think what you're asking for. Though I like hhafez' suggestion better myself.
(Note my answer is now OBE b/c the questioner shifted the methods to be static rather than instance methods. Nevertheless, the tone of other answerers is good... solving this problem by explicit classloading just because you want to select specific static methods is a kludge.)
In your example you in fact have not two different versions of class Foo, but two different implementations of the interface Foo, which is fine in most cases. (They even can exist parallel to each other.)
It is possible to load multiple classes of the same name, but they have to be loaded by different classloaders. This also means that you can't have a third class referencing it by name and then using one or the other (without the third class also being on two classloaders).
Sometimes it may be sensible to have different versions of a class (with same external interface) for different configurations where it would be used (such as "on client side" / "on server side", when some common class in both modules depends on it), and in rare cases you would have both modules in the same VM at the same time - but in most cases it would be better to use the "one interface and multiple implementing classes" approach instead.