Create object from Class instance - java

I want to create objects from different classes extending the same class. Can you explain how it will work. Examples would be nice.
Thank you.
class MainClass{
private <T extends DataPoint> void someMethod(Class<T> clazz) {
new clazz(2,3);//<-- create object of class (did not work)
}
private void anotherClass(){
someMethod(GreenDataPoint.class);
someMethod(BlueDataPoint.class);
}
}
class DataPoint {
int x;
int y;
DataPoint(int x, int y) {
this.x = x;
this.y = y;
}
}
class BlueDataPoint extends DataPoint {BlueDataPoint(int x, int y){super(x,y);...}}
class GreenDataPoint extends DataPoint {GreenDataPoint (int x, int y){super(x,y);...}

It looks like you want to create an instance of a dynamically selected class. Obtain a constructor with getConstructor(), and invoke it with the necessary arguments. The Class object has a newInstance() method which is almost the same, but using a Constructor will report any errors in a manner more consistent with other reflective methods.
Constructor<T> ctor = clazz.getConstructor(Integer.TYPE, Integer.TYPE);
T point = ctor.newInstance(2, 3);

Instead of
new clazz();
try
clazz.newInstance();
Good luck

Related

Define identical treatment of private subclass members in superclass

I've got this parent class:
abstract class Parent {
abstract int getX();
}
And two different subclass implementations:
class AgnosticChild extends Parent {
private int x = 5;
#Override
int getX() {
return x;
}
}
class ManipulativeChild extends Parent {
private static int x = 5;
ManipulativeChild() {
x++;
}
#Override
int getX() {
return x;
}
}
Both getX() implementations are identical. Is there any way to get rid of this redundancy while keeping the different implementations for x? Assume that the getX() implementation is a lot more elaborate in practice.
No, the two implementations are not identical - one accesses a static field, and the other accesses an instance field. So although they look identical, they're functionally very different; and there's no opportunity for re-use here, without changing the behaviour of your classes.
You could pull up the int variable to Parent class and implement getX method there
abstract class Parent {
private int x;
public Parent(int x) {
this.x = x;
}
public int getX() {
return x;
}
}
class AgnosticChild extends Parent {
public AgnosticChild() {
super(5);
}
}
class ManipulativeChild extends Parent {
ManipulativeChild() {
super(6);
}
}
Update: The upper code snippet only equal to your code if you want to declare the x in ManipulativeChild as non-static field. Otherwise these are two different implementation and cannot be refactored in the proposed way.

Getting duplicate fields when setting from Concrete class

I need to define constant values in each ConcreteClass that extends AbstractClass. For some reason object ends up having duplicate fields, one set of fields is equal to zeros, next one has proper values.
SomeInterface
public interface SomeInterface{
double calculate();
}
AbstractClass
public abstract class AbstractClass implements SomeInterface{
double x, y;
public double calculate(){
return x*y;
}
}
ConcreteClass
public class ConcreteClass extends AbstractClass{
final double x = 1.1;
public setY(double y){
this.y = y;
}
}
I need my concrete class to store constant value final double x = 1.1; while inheriting the calculate() method implementation from abstract class.
You have declared x twice, so you get two x variables; one masks the other. It's doing what you told it to.
To have the concrete class set a value, put the setting of it in a (or all) constructor(s) of the ConcreteClass. Don't declare it again.
I don't know a way that you can declare it final and still alter it in a subclass.
You may be able to do something like this to get around - even though you cannot override instance variables in java.
If all you want to do is have Concrete class's have a constant variable, and the base abstract class use that for calculate method - You could try something like this..
public abstract class AbstractClass implements SomeInterface{
double x, y;
public void setX(double x){
this.x = x;
}
public double calculate(){
return x*y;
}
}
Then in the concrete class you could still have the final variable and have that passed in to the abstract class's setter.
public class TestAbstractVariable extends TestAbstract {
{
final double x = 1.1;
setX(x);
}
public void setY(double y){
this.y = y;
}
}
Hope it helps.
Thanks,
paul

use variable with "new" when creating object

I am designing a virtual aquarium. I have a class: Fish which I inherit to create classes of different species. The user can select the species in a combo box and click a button to put the fish in the tank. I use the following code to create the fish:
switch(s){
case "Keegan" :
stock.add(new Keegan(this, x,y));
break;
case "GoldenBarb" :
stock.add(new GoldenBarb(this, x,y));
"stock" is a LinkedList and "s" is the String selected in the Jcombobox. As it stands I will have to create a long switch when I add a bunch of different species. I would like the code to look like:
stock.add(new s(this,x,y));
and dispense with the switch such that all I have to do is create the class and add its name to the combo box and have it work. Is there a way to do so? Any help is appreciated.
You want to use a bunch of factory objects, stored in a Map under the string keys that you use in the switch.
These are the classes for the various fish you should already have.
abstract class FishBase {}
class Keegan extends FishBase {
Keegan(Object _this, int x, int y) {
// ...
}
}
class GoldenBarb extends FishBase {
GoldenBarb(Object _this, int x, int y) {
// ...
}
}
An interface for all the fish factories. A fish factory represents a way to create some type of fish. You didn't mention what the constructor signature is so I just picked some types.
interface IFishFactory {
FishBase newFish(Object _this, int x, int y);
}
Set up one factory for every fish type. These obviously don't need to be anonymous classes, I'm using them to cut down on clutter.
Map<String, IFishFactory> fishFactories = new HashMap<>();
fishFactories.put("Keegan", new IFishFactory() {
public FishBase newFish(Object _this, int x, int y) {
return new Keegan(_this, x, y);
}
});
fishFactories.put("GoldenBarb", new IFishFactory() {
public FishBase newFish(Object _this, int x, int y) {
return new GoldenBarb(_this, x, y);
}
});
Then just pick the factory from the Map using the string you already have. You might want to check whether a factory for the given name exists.
stock.add(fishFactories.get(s).newFish(this, x, y));
Now, if all your fish classes have the exact same constructor signature, you can create a single factory class that can handle all of them using reflection, and get rid of some boilerplate.
class ReflectionFishFactory implements IFishFactory {
Constructor<? extends FishBase> fishCtor;
public ReflectionFishFactory(Class<? extends FishBase> fishClass)
throws NoSuchMethodException {
// Find the constructor with the parameters (Object, int, int)
fishCtor = fishClass.getConstructor(Object.class,
Integer.TYPE,
Integer.TYPE);
}
#Override
public FishBase newFish(Object _this, int x, int y) {
try {
return fishCtor.newInstance(_this, x, y);
} catch (InstantiationException
| InvocationTargetException
| IllegalAccessException e) {
// this is terrible error handling
throw new RuntimeException(e);
}
}
}
Then register it for every applicable subclass.
for (Class<? extends FishBase> fishClass :
Arrays.asList(Keegan.class,GoldenBarb.class)) {
fishFactories.put(fishClass.getSimpleName(),
new ReflectionFishFactory(fishClass));
}
I think reflection might be what you are looking for. This allows you to avoid the switch statement, which is what you are asking.
Reflection (among other things) allows you to run methods with just strings. So in Java, where you would normally call a method like this:
new Foo().hello();
With Reflection, you can use a string to call the method, like this:
Class<?> clazz = Class.forName("Foo");
clazz.getMethod("hello").invoke(clazz.newInstance());
Java Constructor Reflection example.
Regarding the Factory pattern (referring now to other answers), as I understand it, that is just encapsulating the switch statement (or whatever method you choose to use). The Factory pattern itself is not a means of avoiding the switch statement. The Factory Pattern is a good thing, but not what you were asking. (You will probably want to use the factory pattern in any case).
Let's go step by step to see how far you want to go.
First, you can abstract out the creation of fish in a FishFactory, so that the original place you do the switch statement can simply changed to
stock.add(fishFactory.createFish(s, x, y));
Then the switch case goes to the factory:
public class SimpleFishFactory {
#Override
public Fish createFish(String fishType, int x, int y) {
switch(s){
case "Keegan" :
return new Keegan(this, x,y);
break;
case "GoldenBarb" :
return new GoldenBarb(this, x,y);
//....
}
}
}
(I assume all your fish is having same interface/base class as Fish)
If you want to make the creation look more elegant, there are two common ways to choose from:
Reflection
Idea is simple. First setup a lookup table of string vs fish class (or constructor), and each createFish() is creating new instance of fish by reflection
public class ReflectionFishFactory {
private Map<String, Class<? extends Fish>> fishClasses = new HashMap<...>();
public ReflectionFishFactory() {
//set up fishClasses with name vs corresponding classes.
// you may read it from file, or hard coded or whatever
fishClasses.put("Keegan", Keegan.class);
fishClasses.put("GoldenBarb", GoldenBarb.class);
}
#Override
public Fish createFish(String fishType, int x, int y) {
Class<?> fishClass = fishClasses.get(fishType);
// use reflection to create new instance of fish by
// by using fishClass
}
}
Prototype Pattern
For some reason, you may not want to use reflection (maybe due to slowness of reflection, or different fishes have very different way to create), you may look into Prototype Pattern of GoF.
public class PrototypeFishFactory {
private Map<String, Fish> fishes = new HashMap<...>();
public ReflectionFishFactory() {
//set up fishClasses with name vs corresponding classes.
// you may read it from file, or hard coded or whatever
fishClasses.put("Keegan", new Keegan(....) );
fishClasses.put("GoldenBarb", new GoldenBarb(....) );
}
#Override
public Fish createFish(String fishType, int x, int y) {
return fishes.get(fishType).cloneNewInstance(x, y);
}
}
A combination of enums and factory strategies could be used for a simple, type-safe, way of creating object instances from Strings and for providing a set (or array) of Strings.
Take the follwoing eample -
import java.util.HashMap;
import java.util.Map;
public enum FishType {
BLUE_FISH(BlueFish.class, new FactoryStrategy<BlueFish>(){
public BlueFish createFish(int x, int y) {
return new BlueFish(x, y);
}}),
RED_FISH(RedFish.class, new FactoryStrategy<RedFish>(){
public RedFish createFish(int x, int y) {
//an example of the increased flexibility of the factory pattern - different types can have different constructors, etc.
RedFish fish = new RedFish();
fish.setX(x);
fish.setY(y);
fish.init();
return fish;
}});
private static final Map<Class<? extends Fish>, FactoryStrategy> FACTORY_STRATEGY_MAP = new HashMap<Class<? extends Fish>, FactoryStrategy>();
private static final String[] NAMES;
private FactoryStrategy factoryStrategy;
private Class<? extends Fish> fishClass;
static {
FishType[] types = FishType.values();
int numberOfTypes = types.length;
NAMES = new String[numberOfTypes];
for (int i = 0; i < numberOfTypes; i++) {
FishType type = types[i];
FACTORY_STRATEGY_MAP.put(type.fishClass, type.factoryStrategy);
NAMES[i] = type.name();
}
}
<F extends Fish> FishType(Class<F> fishClass, FactoryStrategy<F> factoryStrategy) {
this.fishClass = fishClass;
this.factoryStrategy = factoryStrategy;
}
public Fish create(int x, int y) {
return factoryStrategy.createFish(x, y);
}
public Class<? extends Fish> getFishClass() {
return fishClass;
}
public interface FactoryStrategy<F extends Fish> {
F createFish(int x, int y);
}
#SuppressWarnings("unchecked")
public static <F extends Fish> FactoryStrategy<F> getFactory(Class<F> fishClass) {
return FACTORY_STRATEGY_MAP.get(fishClass);
}
public static String[] names() {
return NAMES;
}
}
This enum could then be used in the following manner -
Fish fish = FishType.valueOf("BLUE_FISH").create(0, 0);
or
Fish fish = FishType.RED_FISH.create(0, 0);
or, if you need to know the type of the created fish, you can use this call -
BlueFish fish = FishType.getFactory(BlueFish.class).createFish(0, 0);
To populate the items in a menu or obtain all fish types for any other reason, you can use the names() method -
String[] names = FishType.names();
To add new types, the only code that needs to be edited is to add a new enum declaration such as
GREEN_FISH(GreenFish.class, new FactoryStrategy<GreenFish>(){
public GreenFish createFish(int x, int y) {
return new GreenFish(x, y);
}}),
It may seem like a lot of code, but it's already been written, it provides a clean API to call from other code, it provides pretty good type-safety, allows the fish implementations the flexibility to have whatever constructors or builders that they want, it should be fast performing, and it doesn't require you to pass around arbitrary string values.
If you are just really into keeping it concise, you could also use a template method in the enums -
public enum FishType {
BLUE_FISH(){
public BlueFish create(int x, int y) {
return new BlueFish(x, y);
}
},
RED_FISH(){
public RedFish create(int x, int y) {
return new RedFish();
}
};
public abstract <F extends Fish> F create(int x, int y);
}
With this, you still get a lot of the same functionality such as
Fish fish = FishType.valueOf("BLUE_FISH").create(0, 0);
and
Fish fish = FishType.RED_FISH.create(0, 0);
and even
RedFish fish = FishType.RED_FISH.create(0, 0);
Study the Factory Design Pattern. That is essentially what you are doing here, but will be a little bit cleaner if you use it explicitly.
It is not always just a giant switch statement. For instance, you may have a table of dynamically loaded assemblies and/or types, each of which have a function called "GetTypeName" and another function called "CreateInstance". You would pass a string to a factory object, which would look in the table for that typename and return the result of the CreateInstance function on that factory object.
No, this isn't reflection, people were doing this long before Java came along. This is how COM works for example.
Reflection seems to be the best solution for this issue and I am glad to have this technique in my toolbox. Here is the code that worked:
public void addFish(String s, int qt){
try{
Class<?> theClass = Class.forName("ftank." + s);
Class[] ctorArgs = {ftank.FishTank.class};
Constructor ctor = theClass.getDeclaredConstructor(ctorArgs);
for(int i=0;i<qt;i++){stock.add((Fish)ctor.newInstance(this));}
} catch (ClassNotFoundException e) {...
I had to include the package name as part of the class string. I also had to make the constructors public. I was unable to implement this solution with int arguments in the constructors but I managed to find a way around using them which was cleaner anyways. The only problem now is that I must update the array of Strings used in the JComboBox everytime
I add a new species of Fish. If anyone knows a way of having java generate a list of the names of all the classes in a package which inherit from a given base class that would be helpful. Your suggestions so far were very helpful and I am greatful.

defer final value to subclass java

I have a question similar to In Java, why can't I declare a final member (w/o initializing it) in the parent class and set its value in the subclass? How can I work around? but which requires a different solution. As in the above case, I want to declare a variable to be Final in the superclass, but I want the subclass to give it the value. What makes my problem different though is that I don't want the value passed in to the subclass, I want the subclass to 'know' its value, so the above solution doesn't work for me. Then I tried to do this:
public class Superclass{
public final int x;
public Superclass(int x){
this.x = x;
}
}
public class Subclass extends Superclass{
public Subclass(){
x = 1;
super(x);
}
}
...which didn't work (the call to super() must be on the first line :/ ). But this is basically the behavior that I want. Is there a good way to do this? Thanks!
You could do
super(1);
so instead of setting x, you are passing the value.
An alternative to the one above:
class Superclass{
public final int x;
public Superclass(int x){
this.x = x;
}
public static Superclass createNew(Integer y) {
return new Superclass(y);
}
public void print() {
System.out.println(this.x);
}
}
class Subclass extends Superclass{
public Subclass(int x) {
super(process(x));
}
public static Integer process(Integer y) {
if (y < 100)
y += 100;
return y;
}
}
I don't have a java compiler handy, but you're attempting to set x = 1 twice in this code.
x = 1;
And
super(x); //==> this.x = x
Do as #Kal said and do super(1), as x = 1 won't work.

Can I make a protected member public in Java? I want to access it from a subclass

I'm new to Java and OOP,
I was using a private subclass (actually a struct) B in a class A, and everything went well until I decided to make a parent class C for subclass B. I want make public some of the protected members of class C.
For example:
public class A {
private class B extends C {
public int product;
public int x;
public int y;
public void add() {
product=x+y;
}
}
B b=new B;
b.x=1;
b.y=2;
b.multiply();
System.out.println(b.product+"="+b.x+"x"+b.y);
public class C {
protected int x;
protected int y;
public int sum;
public C(px,py) {
x=px;
y=py;
}
public void sum() {
sum=x+y;
}
}
And I get
Implicit super constructor C() is undefined for default constructor.
Must define an explicit constructor
Of course, I could remove extends C, and go back to what I had before. Or I could make a getter/setter. But I think it is understandable that an inner struct is acceptable, and it should be able to extend other classes.
The compiler message is reasonably clear - in B you've effectively got:
public B() {
super();
}
and that fails because there's no parameterless constructor in C to call. Either introduce a parameterless constructor, or provide an explicit constructor in B which calls the constructor in C with appropriate arguments.
I'm not sure it's a good idea to have all these non-private fields, mind you - nor is it a good idea for fields in B to hide fields in C. Do you really want an instance of B to have two x fields and two y fields? You realise they will be separate fields, don't you?
If you just want to effectively provide public access, you could have:
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
(and the same for y) and remove the extra fields from B. You can't change the actual accessibility of the fields in C though.
Okay, I was fuddling with my own code and found that the problem is I needed a protected default constructor for superclass C. It works now...

Categories