I'm a Java newbie and ran into a bit of a problem. I want a class to become another class. It's hard to explain it the abstract way, so I'll give you an example.
public class WorldGuard extends WorldGuardPlugin {
public WorldGuard(Plugin parent) {
WorldGuardPlugin plugin = parent.getServer().getPluginManager().getPlugin("WorldGuard")
// make plugin the actual class
}
}
WorldGuard should act like some kind of a wrapper here. When constructed it gets one parameter parent on which base it finds an instance of WorldGuardPlugin. The class should now become that instance.
It's simple in JavaScript, I just return the instance, but I can't do this in Java.
I'm not quite sure what you're trying to do. A class cannot "become another class". But perhaps your problem is just that you're trying to use a constructor when you should be using a plain function. Maybe what you want to do is this:
public class WorldGuard extends WorldGuardPlugin
{
public static WorldGuard getFromPlugin(Plugin parent)
{
return (WorldGuard) parent.getServer().getPluginManager().getPlugin("WorldGuard");
}
}
That would get the object via parent and return it as a WorldGuard object.
Class cannot become other class.
I think you can choose among the following possibilities.
User Factory that creates instance of your classes. The factory will choose concrete class according to any logic you want and create instance of "right" class. If you want all classes the factory operates with can implement specific interface, so caller will not even know instance of which class is created.
Use wrapper pattern. In this case your actual WordGuard class will wrap actual instance of other class and delegate all calls there.
Use dynamic proxy or byte code engineering solution. But it is much more complicated and is not the best solution in most cases.
You should call the copy constructor of WorldGuardPlugin. What I mean is that WorldGuardPlugin should have a constructor that can create a copy of a given instance of the class like:
WorldGuardPlugin pg = new WorldGuardPlugin(anInstance);
If this is the case then you are in luck. You can simply do:
public class WorldGuard extends WorldGuardPlugin {
public WorldGuard(Plugin parent) {
super( parent.getServer().getPluginManager().getPlugin("WorldGuard"));
}
}
This will make "WorldGuard act like some kind of a wrapper here". You can still call the methods defined in WorldGuardPlugin on an instance of WorldGuard while being able to add methods to WorldGuard itself.
You can't change the type of object being constructed in a constructor. A constructor, by definition, constructs that class (e.g. A's constructor creates a type A).
In your example, WorldGuard extends WorldGuardPlugin, which means that WorldGuard is a type of WorldGuardPlugin. Maybe there is a way to initialize the WorldGuardPluin class (using a call to super in the constructor) with the properties that you want.
Related
I'm using an external library where I came across a public class that I want to extend. It's only constructor is package-private, thus invisible to me.
public class Token implements IToken {
Token(int kind, Object source, int offset, int endOffset) {
...
}
...
}
My subclass would be
public class MyToken extends Token {
...
}
This gets an error:
Implicit super constructor Token() is undefined for default constructor. Must define an explicit constructor
When I add a constructor:
MyToken(int kind, Object source, int offset, int endOffset) {
super(kind, source, offset, endOffset);
}
I get the error message
The constructor Token(int, Object, int, int) is not visible
Is there any way to extend this class? If not, what is the purpose of declaring it public?
Any subclass needs to be able to access at least one constructor of the base class.
If you want the subclass to live in another package, you have to make the constructor at least protected.
As this comes from a third-party library, it looks like they do not want you to subclass Token. There is probably an alternative to subclassing for whatever you need to do here.
Not providing a public constructor is a common pattern for when you (the library author) need to control how instances are created (for example to implement singletons, or to enforce use of factory methods).
If not, what is the purpose of declaring it public?
A public class can be used from anywhere, i.e. you can call methods on an instance that you are given (even if you cannot make new instances yourself).
The purpose of a public class with a restricted constructor can be to leave the construction to a friend class, or a static factory (create) method.
This factory pattern might be the case here. Then you can use:
public class MyToken implements IToken {
private Token delegate;
public MyToken(int kind, Object source, int offset, int endOffset) {
// Factory usage:
delegate = Token.create().withKind(kind).withSource(source)...;
}
public int getKind() {
return delegate.getKind();
}
...
Otherwise you could create in the same package as Token a (base) class with a public constructor. With modular java > 8 this trick will no longer be permitted.
My personal guess is that Token will be created by some Parser/Scanner class in the same package. Actually even a child class of Token might be returned, as it then can be a nested internal class wich can access fields of the Parser container, like line as String, filePath.
Creating your own IToken implementation might be the best implementation.
No. It is impossible without changing of Token class.
Some libraries can amend class in run-time, but I strongly discourage you from going this way.
You're allowed to use Tokens, but not to create them. For example, this construction would mean you could probably use something like the below in your program:
List<Token> tokens = stream.getTokens();
So basically the library will create the tokens, and you can work with them but not extend or create any of your own.
Your point is valid around making class public with protected constructor but you could try composition to achieve desired functionality where MyToken class contains reference of Token class. This way, we would be following Composition over Inheritance principle as well.
I've ran into a problem that is new for me. Basically, someone else has already written a class A. The important parts looks like this
class A{
// some instance variables
public A(){
// Calls methods
build();
// Calls more methods
}
private build(){
item = makeItem();
anotherItem = makeAnotherItem();
// more code
}
private makeItem(){
// Does some things and calls updateItem()
}
private updateItem(){
// Does some things with instance variables of class A
// and calls yet another method in class A.
}
My problem is that build() does exactly what I need, but I need it in another class. Now here are the problems:
class A does a whole lot more than the things I've written, and so I cannot create an object of it. It would be pointless.
I've tried copying the build() method for my class B. However, build() uses other methods. And so I have to copy them as well and of course they call other methods and use instance variables declared in some other methods. Basically, I would have to copy 200 rows of code.
I'm guessing this problem actually has a name but I do not know what it's called and have therefore searched some basic terms only. What can I do to use build() in my class B?
You use the code of the build method in two classes but inheritance is not useful? Then you can reuse the code of the build method with composition. (hint Favor Composition over Inheritance) Create a new class C, which contains the build method. The class C is used by the classes A and B via composition. They delegate to the build method of the class C.
See the refactoring method of Martin Fowler.
https://sourcemaking.com/refactoring/smells/duplicate-code
also see
https://sourcemaking.com/refactoring/replace-inheritance-with-delegation
Always refactor in small steps. e.g. Put stuff together that belongs together, perhaps there is a neccessity for another class C which contains makeItem, makeAnotherItem and the corresponding instance variables. There is no general answer and it depends on how your code exactly looks like
first of all if build() in class A is using other private methods of A, that smells like you will need class A itself.
One option could be to create abstract class containing the common methods (including the build method), and extend this abstract class by class A and B. that way you will not have duplicate code
If for some reason you don't want to touch class A, I suggest you create an interface like :
public interface Builder{
void build()
}
and then implement this interface by your class B, and also extend class A so that you have implementation of the build method.
public class B extends A implements Builder{
// build() of class A will be used
// do other staff
}
In doing so, there is no change to class A at all (this might be desired if it is legacy code or something) + Builder can be used as a type in API you want to expose.
I'm creating a grid based game.
I need to implement a set of obstacles that take random positions within the grid.
I've created an abstract class ALifeForm, that holds the common methods for every item within the grid. Obviously, abstract classes can't be initialised, so I was going to create a new class AObstacle, which will extend ALifeForm.
Only issue is, my AObstacle class isn't specialised. All the methods it needs are within ALifeForm.
Can I have an empty class?
Is it bad programming practice? And if so, what can I implement instead?
Of course...
class AObstacle { }
(Plus whatever inheritance model you're using.) There's nothing stopping you from doing this.
Remember that a class isn't really a thing that you're defining. A type is. The class is just the language/syntax construct used to describe the type. If the type being described has no attributes or operations aside from the inheritance model, then there's nothing else to add to it.
Though you are adding one thing. You're giving it a name. It doesn't sound like much, but defining a semantic concept with a concrete name (particularly in a statically typed environment) is very important. Your type now has an identity apart from other types in the system. If things are added to it later, there's a place to add them without refactorings and breaking changes.
Well to do it you don't need to have an abstract class and a class that extends it, or an empty class(wich is possible too).
First way:
You just need to implement two classes: The class that contains the methods and the variables you need to use and the second calss that has an instance of your first class:
public class A{
public void firstMethod(){
//do your stuff here
}
....
}
public class B{
public static void main(String[] args) {
A a=new A(); //instantiate your class here
a.firstMethod();// then just use its methods
}
}
Because if you implement a class that extends an abstract class it should implement all its methods.
Second way:
Or if you want your second class to be specialized you could have :
your first class wich should not be abstract and the second one can extend it and use all its methods, and have its specific methods
In my UI project, I have few screens that share the same header style only the text is specific to the screens. What will be a good way to implement this?
Have the super class create all the header component and open the components to the sub class, the sub class will access to component's setText method to update the text?
or
Have abstract method in super class to create the components, sub class will implement these methods to create the component.
Hope it make sense..
Do you really need an abstract class?
public class UIScreen {
public UIScreen(String headerText) {
//set everything up here w/ the right text
}
}
// elsewhere ....
UIScreen mainScreen = new UIScreen("Main Screen");
Create the abstract class with the generic header method, and define one method for all the subclasses to implement would be best.
Depends on whether you want the super class able to be instantiated or not. It's like having an Animal super class and Dog and Cat subclasses. Do you want people to be able to create a generic Animal?
If so, it should be a normal class. If not, it should be declared abstract.
So ultimately the question is: Is there a default behavior? If not, then make it abstract.
The second option is more viable.
Remember: Single Responsibility Principle
Both options work but the second one will go a longer way to reduce coupling in your code.
When the behaviour Keeps changing...encapsulate it in either abstact class or interface.
Its better to have an
Abstract class, with the non-abstract method to create the Header,
and an Abstract method to create the text
..In the sub class u can create the text of your choice by implementing the abstract method.
"Have abstract method in super class to create the components, sub class will implement these methods to create the component."
In my opinion this solution is easier to maintain.
You can change your option 1 slightly
public abstract class SuperUI {
private HeaderComponenet headerComponent;//have getter setter
}
public class BaseUI extends SuperUI{
private void changeHeaderComponent(){
headerComponent.setText("Changed");
}
}
public class HeaderComponent extends JComponent{
public HeaderComponent(){
//create the default header here
}
}
In this case if the default header component has to be changed you don't have to change your SuperUI, as you have separated the header from SuperUI, you can do the same for footer component if need be.
My question is does the subclasses have any useful functionality? If not, why wouldn't you just have the one concrete class and pass it some sort of data container to populate the fields?
If there's no behavioral differences, you'd be much better served just passing data and/or collaborators into either the constructor, or via property setters.
It's been about 6 years since I've written Java, so please excuse the rust.
I'm working with a library method that requires that I pass it Class objects. Since I'll have to invoke this method a dynamic number of times, each time with a slightly different Class argument, I wanted to pass it an anonymous class.
However, all the documentation/tutorials I've been able to find so far only talk about instantiating anonymous classes, e.g.:
new className(optional argument list){classBody}
new interfaceName(){classBody}
Can I define an anonymous class without instantiating it? Or, perhaps more clearly, can I create a Class object for an anonymous class?
Unfortunately, there's no way you can dodge the instantiation here. You can make it a no-op, however:
foo((new Object() { ... }).getClass());
Of course, this might not be an option if you have to derive from some class that performs some actions in constructor.
EDIT
Your question also says that you want to call foo "each time with a slightly different Class argument". The above won't do it, because there will still be a single anonymous inner class definition, even if you put the new-expression in a loop. So it's not really going to buy you anything compared to named class definition. In particular, if you're trying to do it to capture values of some local variables, the new instance of your anonymous class that foo will create using the Class object passed to it will not have them captured.
short answer
you cannot (using only JDK classes)
long answer
give it a try:
public interface Constant {
int value();
}
public static Class<? extends Constant> classBuilder(final int value) {
return new Constant() {
#Override
public int value() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}.getClass();
}
let's creating two new class "parametric" classes:
Class<? extends Constant> oneClass = createConstantClass(1);
Class<? extends Constant> twoClass = createConstantClass(2);
however you cannot instantiate this classes:
Constant one = oneClass.newInstance(); // <--- throws InstantiationException
Constant two = twoClass.newInstance(); // <--- ditto
it will fail at runtime since there is only one instance for every anonymous class.
However you can build dynamic classes at runtime using bytecode manipulation libraries such ASM. Another approach is using dynamic proxies, but this approach as the drawback that you can proxy only interface methods (so you need a Java interface).
You can only reference an anonymous class ONCE. If you do not instantiate it there, you cannot instantiate it since you do not have a name for it.
Hence I believe that anonymous classes can only be used in conjunction with a "new BaseClass()".
In your situation you would pass a BaseClass object to your method doing the work, and instantiate the anonymous object in the source code when you need the object to pass.
You can't access the Class object of an anonymous class without instatiating it. However, if you only need access to the class, you could define local classes within your method and refer to these using the ClassName.class literal syntax.
You can assume the name of an anonymous class and call Class.forName("mypackage.MyBaseClass$1") to get a handle to an anonymous class. This will give you the first anonymous class defined in your MyBaseClass, so this is a rather fragile way to refer to a class.
I suspect whatever you are trying to do could be done a better way. What are you really trying to achieve? Perhaps we can suggest a way which doesn't require you to pass a Class this way.
You can access the class object of an anonymous class by calling .getClass() on it immediately after creation. But what good would that do?
I think the key is in this part of what you said:
I'm working with a library method that requires that I pass it Class
objects.
Why does it want you to pass it Class objects? What does this library do with the Class objects you pass it? Instantiate objects? But if so, what constructor does it use and how does it decide what arguments to pass? I don't know what library you are using or what it does, but I would guess that it always creates objects using the no-argument constructor. However, that will not work for anonymous classes anyway, since they have no public constructor (and in any case, to instantiate any non-static inner class, a reference to the outer instance must be provided, so there is no no-argument constructor).