I wish to create a useful base Java class with a few protected methods and hooks so subclasses can be easily implemented.
However, I wish this class to ONLY be available for deriving a subclass, but not available as a dependency.
The reason is to prevent some junior/careless developers from coupling their code to this base class.
For example, if my base class is called BaseActivity.java, anyone can create their own
public class MyNewActivity extends BaseActivity
But no one can refer directly to BaseActivity with a field or method signature, for example this should not be allowed:
public void doSomethingOnBaseActivity(BaseActivity activity);
private BaseActivity someField;
public BaseActivity getActivity();
Is there any way to accomplish such a restriction in Java?
Maybe in Kotlin this would be possible?
EDIT:
This is NOT a duplicate of Kotlin: Can an abstract super class have an abstract constructor?.
I wish to prevent dependency on the base class, not just instantiation. "Abstract" doesn't help here.
No, this is not possible. This answer is true for all types, whether abstract or not, interface or class. When you are in the scope of a class (e.g. same package), and this class is not sealed then everybody in this scope can inherit it. As long you are inside the scope, you can reference this type. That's the point of access modifiers. It doesn't make sense to allow extension of a type but not referencing it. This contradicts the concept. Why would you want to do that? You can't remove that base class anyway because that would break the code of all inheritors. There is no point in allowing extension but disallowing referencing. What is the reason for this. Maybe there is a different way to accomplish your goal. The very moment somebody inherits from a type creates the dependency. This dependency is called inheritance. The subtype is a supertype. You can't hide this fact from the compiler.
If you want to omit a dependency but reuse code or provide a template of the code then don't use a type. You could use file templates or a code generator to generate the reusable code (like code snippets).
First off, let's address the why. Why are you looking for this? You're looking for a way to prevent the consumer from calling unwanted methods on a base class.
If you think you're looking for something else, think again. If you just want to hide it, think again. The end user will not care about implementation details at all.
If you created the base class, then don't publish an API that allows this in the first place. There was a chapter on this specifically in Clean Code.
If your base class extends another base class you're in trouble. You can't hide already published API, if you're extending and not encapsulating.
I wish this class to ONLY be available for deriving a subclass, but not available as a dependency. Is there any way to accomplish such a restriction in Java? Maybe in Kotlin this would be possible?
No. This is not an opinion, this is by design.
There may be a convoluted way to hide methods of parent classes but not on the class the consumer interacts with (extends).
You could have several layers of base classes each within its own Gradle module and setup implementation type dependency but then If you can extend the class, if you can see it, reference it, you can also use it anywhere.
Imagine this:
consumer module -> ConsumerActivity extends ExtensibleActivity
your library module -> ExtensibleActivity extends BaseActivity
your base library module -> BaseActivity extends Activity
Android SDK -> Activity
Consumer module only sees what's inside "your library module". It knows about ExtensibleActivity but it can't see any of its super types. The consumer can still reference ExtensibleActivity and its methods. The side effect is because the superclasses are not known from consumer's point of view, you can't pass an instance of ExtensibleActivity as an Activity because the type system doesn't know it extends an Activity, because it doesn't see the BaseActivity intermediary type. Here's a graph of what the consumer sees:
ConsumerActivity -> ExtensibleActivity -> BaseActivity (doesn't exist) -> ??? (don't know)
At this point you just have to ask yourself "should this have extended Activity in the first place?".
This is just terrible to work with. Lot of wasted effort for something that you shouldn't need to worry about.
If you want to conceal something, use composition over inheritance. Put your logic inside a Fragment or, better yet, put your logic inside a custom lifecycle aware component. That way you're in total control over the API. Make it so you don't have to worry about where it gets called from.
Write good documentation for your code and a usage manual.
And kindly allow me to break your damn library if I choose to use it incorrectly.
Do you have multiple methods in your API? Great! Nobody will prevent me from calling them out of order. You can write in your manual how it's supposed to be used, but ultimately, I'm writing my program, using your library, and if I do it wrong, then it's my fault when it breaks. This is fine.
Related
There are a large number of classes in this codebase which use a specific interface. However, picking a few at random, I've been unable to find one which is actually called anywhere; as such, I don't have a great idea of how to use it.
Is there a way in Eclipse to find every instance of any class which implements this interface?
In other words, suppose there exists an interface Interface, and classes ClassA, ClassB, ClassC, ..., ClassX, which all implement it. I want to see every point in the code where something like `ClassX obj = new ClassX(). Most of the classes I'm finding that implement this interface don't have any point where they're actually used; I assume they're for future use.
Open the interface class, hold Control and move your mouse to interface's name, select open implementation. That's the simplest and easiest way to do.
Yes, highlight the interface name and hit F4 or right click -> Open type hierarchy.
Update after OP's edit:
If you are using a framework that uses dependency injection like spring probably you don't find any reference because some of the implementations are defined in a xml file.
Also consider if some implementations are created and invoked via reflection.
Some classes might be loaded during runtime e.g. using reflection. To catch-them-all you can set a method entry breakpoint on the interface method. This is explained in this answer. That way all calls to implementation methods will suspend the JVM regardless of what is the object type.
Do note that unlike the line breakpoints the method breakpoints will really slow down the performance of the JVM.
There is a class called CellSignalStrength that does not have a default constructor.
To be able to use SignalStrength, I have to make a class that extracts it, but I can't because when I try to do that, it prints out the error:
No default contstructor available for SignalStrength.
Also, there is another class called CellSignalStrengthGsm(same problem), but that class extends SignalStrength class, but how?
I've done some research on this, and i couldn't find anything, but this guide is only offering the signal strength of neighboring cell-sites to me, none of them is the one providing me with the signal. That solution is offering no actual signal strength.
Why doesn't the Android documentation have at least one example for how to use the class?
I really need help on this, I'm stuck :/
The only reason I can think of why you can't extend the CellSignalStrength class is because its constructor is protected CellSignalStrength(). Meaning only other classes in the same package may extend it.
The Android developers probably had good reason to do so. My suggestion would be to rethink what you're trying to do and figure out another solution. Perhaps using an instance of one of the classes that sub-classes CellSignalStrength:
Note: These classes are all final, so don't try to extend them.
CellSignalStrengthCdma
CellSignalStrengthGsm
CellSignalStrengthLte
CellSignalStrengthWcdma
We have some portion of functionality packed in an external library and it is attached to our project. That library can't be changed in any way. Amongst others there are two classes lying inside it: com.myorg.Grandpa and com.myorg.Dad that extends com.myorg.Grandpa. Also there are com.myorg.Grandson extending com.myorg.Dad and a few other classes outside of the library extending com.myorg.Grandpa.
I decompile com.myorg.Grandpa class and add a new method new_method() to it.
Then I try to use new_method() in com.myorg.Grandson but IDEA won't let me do it cause Grandson extends Dad which extends library's Grandpa which doesn't contain new_method().
I tried to delete Grandpa from library and surprisingly IDEA didn't say a word and successfully compiled a project despite of the fact that in the boundaries of a library Dad extends non existing class.
The question is how to force Dad to extend a new Grandpa without deleting the one inside a library?
You could
Add an abstract class between Dad and GrandSon: Extend Dad, and add your method in the sub class. Then derive GrandSon from that sub class.
Put an instance of Dad in a new class, and let your IDE create delegate methods to the aggregated Dad instance. Again add your new method to the new class.
There is another possibility:
If you have to modify classes in place, use aspectj to weave in code: aspectj changes the byte-code (it does not need source code) at run-time. This way you can add methods or fields.
The fact is that you are duplicating classes with full package signature, so you will get the one that the classloader loads first. I know that in Websphere you can tweak classloader priorities, but couldn't say in your case.
Anyway, why not just do it without decompiling? You are causing yourself hard coupling to an external library and bad practices (maybe copyright issues) by decompiling/customizing. Besides, if the library gets updated, you will run into trouble having to reconstruct your customized classes.
Options:
Create your own implementation, for instance:
Create an Interface that replicates all methods in Grandpa plus the one you need.
Extend Grandpa class and implement the added method from your interface, all other methods will be left intact.
Extend all other extending classes from your own class hierarchie.
Instead of using the libraries common class, use your Interface as naming
This way you are kind of creating your own interface to the library, if it changes, you know where to make changes.
You could even do it without the interface, it's kind of wrapping the functionality, it would depend on what you need to achieve.
Anyway, I would try to solve it by own code and not by messing up with the library, it is just not worth it to do such tricks, if a new Programmer takes the project, they will need a lot of time to find out why and how it behaves.
Now, there might be variations in how to structure the class hierarchie, but it would depend on the specific implementation you need, so you would have to post more detailed data on what the library is and what you're trying to add to it if you expect some more specific answer...
Regards
It has to appear first to the class loader.
IDEA should load your class first if is in your project. You may also try to create a separate library for your class and include it in your project.
See also: http://www.jetbrains.com/idea/webhelp/configuring-module-dependencies-and-libraries.html
There is a library have a base class (let's call it CBase) that performs some tasks and one can create classes that extends this CBase class.
The behavior of the CBase is not enough for me, so I would like to create my own CBase class (let's call it MyCBase) that have the same methods and members but these methods don't do the same thing.
Until now everything is ok. But what blocks me is that I would like to replace CBase by MyCBase. However, I have a lot of classes that extend CBase and I don't want to change them all.
Is it possible to replace CBase by MyCBase at runtime ?
So that
public class A extends CBase {}
becomes
public class A extends MyCBase {}
Can I perform this using code enhancement ? (like we do to add methods to a class at runtime. Is it also possible to change inheritance this way ?)
Thank you for your help !
EDIT
I would like to write a plugin for a framework, this is why I would like to change inheritance at runtime. This way users of the framework can use my plugin without changing their source code (changing the inheritance of their classes from CBase to MyCBase)
EDIT 2
Is it possible to do like this: ?
CtClass cc = CtClass.forName("pkg.AClass");
cc.setSuperclass(CtClass.forName("mylib.MyCBase"));
cc.compile();
I'm not expert. Probably you could extend ClassLoader. But I highly recommend don't do it. The replacement will touch many of your classes but it will be clear in code reading and app execution.
I think there is also room for architecture improvement since you have so many classes extend CBase. People are trying to remove dependencies from other libraries or keep it really small. Because in this case you could easily switch to another library or add your own functionality.
I dont think you can change the extends of a class at runtime. I would suggest to change the extends of the objects or build an interface, which contains all the things your need
Changing all derived classes is a simple matter, provided you control their source code:
Create a new class in your project. Call it CBase, and put it in the same package as the library class.
Use the rename/move refactoring of your IDE to rename CBase to MyBase. This will have the IDE rename all references to the renamed/moved class ...
Write the code for MyBase, extending from CBase.
If you can not do this (for instance because some derived classes are in a library you do not control), you replace the implementation of CBase with your own. Simply create a class of the same package and name in your project (the classloader searches the classpath in order, and uses the first class of the proper package and name it finds). This approach however is very brittle, as the compiler can not check binary compability between the old and new version of CBase. The JVM will check this compatibility when classes are loaded, but since classes are only loaded when needed, its hard to test your changes. (Which is why I do not recommend this approach if there are other options).
You could also change the classes as they are loaded my manipulating the class file, that that's going to be even more brittle, and the compiler would allow you to use any additional features MyBase might have. ==> Definitely not a good idea.
I am trying to use the Interactive Brokers Java API to see if I can do some algorithmic trading (on paper initially). I want to call a method called ReqMktDepth() which is in a class called EClientSocket.
The EClientSocket constructor requires an object of type AnyWrapper to be passed, and AnyWrapper is an interface not a concrete class. In theory how do I go about passing an AnyWrapper class to the EClientSocket constructor.
You need to create a class that implements AnyWrapper (using the "implements" keyword) and then you must provide the definitions for any methods defined by that interface.
Here's one simple tutorial:
http://www.uweb.ucsb.edu/~cdecuir/Polymorphism.html
You can either create your own class which implements AnyWrapper interface as Bobby suggests. or Use any other class(present in the library/jar/namespace) which already extends from AnyWrapper interface like the EWrapper, class which already has an implementation of AnyWrapper.
see -> http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/java/eclientsocket.htm
You should probably use some class in that API you use which implements the AnyWrapper interface. You could have a look into the JavaDoc of that API or use your IDE's features (something like show type hierarchy) to find out which classes implement AnyWrapper, and pass one of them.
Several other answers have pointed out that you can create an instance of AnyWrapper by either implementing it yourself or by finding an existing class and passing in an instance of that class.
However it seems to me that what you are doing is not likely to succeed. You are trying to call a method whose argument is completely unknown to you. You need to read the documentation about that method and find out what the AnyWrapper is for and how it will be used. Maybe there just needs to be something provided, but maybe AnyWrapper has some responsibility that the EClientSocket needs.
This kind of programming by trial and error can lead to some serious problems down the road. For one thing, certain methods are not safe to call unless other safeguards are taken. Certain methods have major performance or security implications. In this case I think you really need to find out what it is you're trying to do before you figure out how to do it.