I have two classes which both extends Example.
public class ClassA extends Example {
public ClassA() {
super("a", "class");
}
...
}
public class ClassB extends Example {
public ClassB() {
super("b", "class");
}
...
}
public class Example () {
public String get(String x, String y) {
return "Hello";
}
}
So thats all very well. So suppose we have another class called ExampleManager. With example manager I want to use a generic type and consequently return that generic type. e.g.
public class ExampleManager<T extends Example> {
public T getExample() {
return new T("example","example"); // So what exactly goes here?
}
}
So where I am returning my generic type how do i get this to actually work correctly and cast Example as either classA or classB?
Many Thanks
You can't use a generic type to instantiate new object (i.e. you can't do new T(params)).
When you are creating a concrete instance of object (that is, you use new), you have know the actual implementing class, you can't use a generic type.
What are you actually trying to achieve? How do you decide whether you want to create ClassA or ClassB?
Try this:
public class ExampleManager {
public ClassA createClassA() {
return new ClassA("example","example");
}
public ClassB createClassB() {
return new ClassB("example","example");
}
}
or this:
public class ExampleManager {
public Example createExample() {
if(a == b) {
return new ClassB("example","example");
}
return new ClassB("example","example");
}
}
As others have said, you can't use new to create a new instance of an unknown type. Without using reflection, you could make ExampleManager an abstract superclass of factories.
public abstract class ExampleManager<T extends Example> {
public abstract T getExample(String x, String y);
}
public class ClassAManager extends ExampleManager<ClassA> {
public ClassA getExample(String x, String y) {
return new ClassA(x, y);
}
}
public class ClassBManager extends ExampleManager<ClassB> {
public ClassB getExample(String x, String y) {
return new ClassB(x, y);
}
}
Related
I'm probably going about this in the most complicated way, but I'm hoping what I'm trying to do makes sense here.
Suppose I have some set of unrelated, generated classes and I want to Decorate them to create some kind of common API. So something like:
public abstract class GeneratedDecorator<T> {
private T generated;
public T getGenerated() { return generated; }
public void setGenerated(T generated) { this.generated = generated; }
public abstract String getString();
public static class ClassA extends GeneratedDecorator<GeneratedClassA> {
#Override
public String getString() { return getGenerated().getThisString(); }
}
public static class ClassB extends GeneratedDecorator<GeneratedClassB> {
#Override
public String getString() { return getGenerated().getADifferentString(); }
}
}
Now, to use this new fancy class I just say:
GeneratedDecorator.ClassA a = new GeneratedDecorator.ClassA();
a.setGenerated(myGeneratedInstanceA);
a.getString();
Ok so far so-so ... but now I want to manage an array of these Decorators.
So let's try:
public abstract class DecoratorBundle<T extends GeneratedDecorator> {
private static final int MAX_ROWS = 10;
private T[] bundle;
DecoratorBundle() { bundle = createBundle(); }
public String getString(int index) { return bundle[index].getString(); }
public void setRow(??? generated, int index ) {
//check index of bundle, if null create a new instance of appropriate type and set bundle[index] = new instance
//call setGenerated on instance at index
}
protected abstract T[] createBundle();
public static class ClassA extends DecoratorBundle<GeneratedDecorator.ClassA> {
#Override
protected GeneratedDecorator.ClassA[] createBundle() {
return new GeneratedDecorator.ClassA[MAX_ROWS];
}
}
public static class ClassB extends DecoratorBundle<GeneratedDecorator.ClassB> {
#Override
protected GeneratedDecorator.ClassB[] createBundle() {
return new GeneratedDecorator.ClassB[MAX_ROWS];
}
}
}
Here's where I'm stuck ... I want this DecoratorBundle to have a setRow(??? generated, int index) where the parameter is of the GeneratedDecorator's type (i.e, GeneratedClassA or GeneratedClassB). Seems like type erasure will probably make this impossible, but it would be really nice to have this DecoratorBundle class to completely manage it's bundle array. It currently is able to instantiate the array, but I want some way for it to create a new GeneratedDecorator-type and assign it in a setRow method.
If I'm going about this completely wrong then I would love to hear another idea.
I've got next situation:
There is an abstract class
public abstract class SuperClass {
public abstract void getString();
public abstract void method2();
}
public class InheritClass1 extends SuperClass {
#Override
public void getString(){...};
#Override
public void method2(){...};
}
public class InheritClass2 extends SuperClass {
#Override
public void getString{...};
#Override
public void method2(){...};
public void customMethod(){...};
}
There is another class that has a method that accepts SuperClass object as an argument. Depending on what kind of String is returned from getString I perform different actions. My case is that I am trying to call a child method while the object is of parent class:
public class Processor {
public String method(SuperClass type) {
switch (type.getString()) {
case "1":
return "OK"
case "2":
return ((InheritClass2) type).customMethod()
}
}
I do understand that this is BAD DESIGN, could you please help me with finding the best solution for this problem. Maybe generics are suitable in this case somehow. Also the thing is that customMethod() should be a part of not all classes.
Since only some (sub)classes implements customMethod, I would suggest to create an interface that contains this method:
public interface CustomInterface {
public String customMethod();
}
Your SuperClass can then remain just as it is. Only the subclasses/child classes that have customMethod, would then extend your SuperClass as well as implement this CustomInterface. This way, the child classes that do not implement CustomMethod (does not have the method in their class, such as InheritClass1 in your example), also remain just as they are.
Only child classes that have CustomMethod, such as InheritClass2 would then need to change slightly by saying it implements this new interface:
public class InheritClass2 extends SuperClass implements CustomInteface {
// the rest stays the same
}
Then in the section where you want to do the casting, you rather do the following:
public class Processor {
public String method(SuperClass type) {
switch (type.getString()) {
case "1":
return "OK"
case "2":
String s = "";
if (type instance of CustomInterface) {
s = (CustomInterface type).customMethod();
}
return s;
}
}
}
Using the interface in this way will help that you can implement all child classes and not just one as implementing the CustomInterface, and thus, all child classes will work with using instanceof and casting to the interface to call customMethod() - you won't have to handle each child that needs this method separately.
NOTE: Your code is clearly simplified example, it is unclear if the getString() method is just returning an identifier of the child classes in order for you to know which ones you can cast and then call custom Method on... If this is the purpose of your switch and getString methods - to identify which types implement the customMethod() and to call that method, and for any child class that does not have that method to return just "OK" - then you could instead do the following:
public class SubClass1 extends SuperClass implements CustomInterface {
// other mehtods...
public String CustomMethod() { return "SomeString1"; }
}
public class SubClass2 extends SuperClass {
// other methods...
// this subclass does not have the CustomMethod()
}
public class SubClass3 extends SuperClass implements CustomInterface {
// other methods...
public String CustomMethod() { return "SomeString3"; }
}
Then your Processor could look like this:
public class Processor {
public String method(SuperClass type) {
return (type instanceof CustomInterface) ? ((CustomInterface) type).CustomMethod() : "OK";
}
public static void main(String[] args) {
Processor p = new Processor();
SuperClass obj1 = new SubClass1();
SuperClass obj2 = new SubClass2();
SuperClass obj3 = new SubClass3();
System.out.println(p.method(obj1)); // prints: "SomeString1"
System.out.println(p.method(obj2)); // prints: "OK"
System.out.println(p.method(obj3)); // prints: "SomeString3"
}
}
If you don't understand the ternary operator then you can read about it here That's the condition ? exprTrue : exprFalse syntax. It's a short if else statement basically.
You can create an interface, with default custom method implementation, like:
interface A {
default String customMethod() {
return "";
}
}
And abstract class will implement this interface:
public abstract class SupperClass implements A {
public abstract String getString();
public abstract void method2();
}
Bad design will cause you to get bad answers. If you don't want to cast your object to a child object. You could use reflection.
import java.lang.reflect.Method;
public class Processor {
public String method(SuperClass type) {
Method[] methods = type.getClass().getMethods();
for (Method m : methods) {
if (m.getName().equals("customMethod")) {
try {
return m.invoke(type);
} catch (Exception ex) {
// throw
}
}
}
return "OK";
}
}
Depending on your design you could apply:
if (type instanceof InheritClass2.class) return type.customMethod();
or
if (type.getClass() == InheritClass2.class) return type.customMethod();
I am in a situation as follows.
I have an interface A which is inherited by class B,C,D (B,C,D implements A).
public interface A{
public String someMethod();
}
class B implements A{
ObjectType1 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
}
class C implements A{
ObjectType2 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
class D implements A{
ObjectType3 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
As you can see all method implementations are the same. So I am duplicating code. My plan was to move the method to A and make A an abstract class. But the problem is my method depends on the model field. So what would be my options to make this code better?
bdw class A,B,C extends and implements other classes too.
EDIT
modification in code. check field
I don't see any problem related to the model field transforming the interface A into an abstract class.
There is no need to reimplement the method in the subclasses if it is the same, unless you want to change its behavior (override it).
public abstract class A {
// Make it protected so it can accessible by subclasses
protected Object model;
// Common behavior that will be inherited by subclasses
public String someMethod() {
if (model instanceof X) {
return "x";
} else {
return "not x";
}
}
}
public class B extends A {
// Subclasses may access superclasses fields if protected or public.
public void someOtherMethod() {
System.out.println(super.model.toString());
}
}
public class C extends A {
// You may wish to override a parent's method behavior
#Override
public String someMethod() {
return "subclass implements it different";
}
}
For your new code example, if you really want to do that in a procedural way you can create an abstract superclass ObjectType and then it will be accessible for the parent as well.
However I wouldn't do that. It seems to me that in doing so is the very opposite of what object orientation tries to solve.
By using a subclass to define the behavior, you wouldn't need to do it in a procedural logic. That's precisely then point of using objects, inheritance and overriding/implementing behavior as needed.
Create a parent class A with said field, and said function. Have the other classes extend A. No need to override them if they function the same.
To deduplicate, you can either make A an abstract class and move the implementation of the method and the field there, or create an abstract class, say E, that implements the interface with that method and field and then have B, C and D extend that class E.
For the more general question of depending on a subclass's field, you can create an abstract method getModel which the subclasses decide how to implement -- by returning a model field or doing something else.
If you are using java 8 you could use default method in interface A, with a getter method for model.
public interface A{
default public String someMethod() {
if(getModel() instanceof X){
System.out.print(true);
}
}
public Object model getModel();
}
Then implement getModel method in all child interfaces.
If you're going to do this you must have model to be of the same (basic) type in all derived objects. If it were of the same type there's a case for putting the model to a base class. Anyway if they are of different derived types you would need to have an accessor to get it.
interface B {
BaseModel getModel();
default public strict doSomething() {
BaseModel m = getModel();
// do something with m
}
}
class D implements B {
DerivedModel model;
public getModel() {
return model;
}
}
If I was given a chance to refactor it, I will follow below approach, leveraging Java 8 Default Methods:
interface A {
default String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return something, for now returning class
return objectType.getClass().toString();
}
}
class B implements A {
#Override
public String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return "Hello"
return "Hello";
}
}
class C implements A {}
class D implements A {}
Usage:
public class Main implements A {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
Main main = new Main();
main.call(b);
main.call(c);
main.call(d);
}
public void call(A clazz) {
ObjectType1 objectType1 = new ObjectType1();
String type = clazz.someMethod(objectType1);
System.out.println(type);
}
}
interface X {
}
class ObjectType1 implements X {
}
I try to implement a fluent interface in my 2D game engine.
Simplified example of my implementation:
public class Sprite<T> {
protected float x = 0.0;
protected float y = 0.0;
public T setPosition(float x, float y) {
this.x = x;
this.y = y;
return (T)this;
}
}
public class Living<T extends Living> extends Sprite<Living> {
protected boolean alive = false;
public T setAlive(boolean alive) {
this.alive = alive;
return (T)this;
}
}
public class Entity<T extends Entity> extends Living<Entity> {
protected String name = null;
public T setName(String name) {
this.name = name;
return (T)this;
}
}
Entity entity = new Entity().setPosition(100, 200).setAlive(true).setName("Zombie");
I keep getting the error: "The function setAlive(boolean) does not exist."
I know, using my methods the other way round (in a more logical order) works:
Entity entity = new Entity().setName("Zombie").setAlive(true).setPosition(100, 200);
And I know that overwriting any parent setter functions in each and every child class would work:
public class Entity extends Living {
protected String name = null;
public Entity setPosition(float x, float y) {
return (Entity)super.setPosition(x, y);
}
public Entity setAlive(boolean alive) {
return (Entity)super.setAlive(alive);
}
public Entity setName(String name) {
return (Entity)super.setName(name);
}
}
But I want the interface to be as free/uncomplicated as possible for the 'end user' and the code to be as compact and clean as it gets.
I don't know if I just messed up the generics or my hole approach is completely wrong. I hope you can help. I am open to any advice. (Sorry for my bad english.)
Edit:
I already tested the following approach and it works for the Entity class.
public class Sprite<T> {
...
}
public class Living<T> extends Sprite<T> {
...
}
public class Entity extends Living<Entity> {
...
}
I forgot to mention, that I need to instantiate Sprite & Living too. For example:
Living living = new Living().setPosition(50, 50).setAlive(false);
This is a valiant attempt at the curiously recurring template pattern in Java. The problem is that you're mixing generics and raw types which means you aren't "closing the loop" of the pattern. For example your declaration of Living:
public class Living<T extends Living> extends Sprite<Living>
Should really be:
public class Living<T extends Living<T>> extends Sprite<T>
At some point you'll need to declare a "leaf" class that resolves T, otherwise you won't be able to instantiate and declare variables of these types without resorting to raw types or wildcards (which defeats the purpose of the pattern). For example:
public final class ConcreteEntity extends Entity<ConcreteEntity>
See my answer here for more details on implementing this pattern.
I think your class model is over complicated, you can pass generic parameter down to the child class and then declare it explicitly:
public class Sprite<T> {
...
}
public class Living<T> extends Sprite<T> {
...
}
public class Entity extends Living<Entity> {
...
}
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}