I thought I understood how to use .class and Class<> but I guess not. The below super(ApprovalWorkstation.class is not being mapped to the constructor. How can I be sure that I'm passing a class reference so that the base WorkstationRequest can instantiate it?
public class ApprovalWorkstation extends Workstation {
public ApprovalWorkstation(WorkstationEntity entity) {
super(entity);
}
}
public class WorkstationRequest extends com.production.socket.request.WorkstationRequest {
public WorkstationRequest() {
super(ApprovalWorkstation.class); //unable to map to constructor
}
}
This is the base WorkstationRequest that's extended above
public class WorkstationRequest {
private Class<Workstation> workstationClass;
public void WorkstationRequest(Class<Workstation> workstationClass) {
this.workstationClass = workstationClass;
}
update
I'm sorry for the confusion, my constructor actually has Class<Workstation> and not Workstation as I initially had.
In order to be able to pass both Workstation class and it's child classes you should change definition of WorkstationRequest to the following:
public class WorkstationRequest {
private Class<? extends Workstation> workstationClass;
public WorkstationRequest(Class<? extends Workstation> workstationClass) {
this.workstationClass = workstationClass;
}
}
Correct me if I am wrong, but you are passing in a Workstation instance while what needed is a Class<Workstation>. Maybe use workstationClass.getClass() instead?
You're trying to assign an instance of Worstation to field of type Class<Workstation> which is obviously not the same.
What you're probably trying to do is:
public WorkstationRequest(Class<Workstation> workstationClass) {
Of course there is no return type (void) in constructors. Your "constructor" is simply a method:
public void WorkstationRequest(Class<Workstation> workstationClass) { // method
public WorkstationRequest(Class<Workstation> workstationClass) { // constructor
There is no constructor that takes a Class as a parameter in the base WorkstationRequest class.
Constructors do NOT have a return type, so public void WorkstationRequest needs to be changed to public WorkstationRequest.
Related
OK, so I'll start this with an example:
Let's say we have an abstract class with an interface variable, which is initialized in the constructor. The abstract class itself has a getter for that variable, it's subclasses have implementations of the interface in the constructor.
Now, the problem I'm getting is that when trying to call the getter of any of the subclasses (which is only declared in the superclass, but it should use the variable declared in their constructors) it doesn't return the implementation, it returns the interface itself.
public abstract class AbstractClass {
private final ExampleInterface exampleInterface;
public AbstractClass(ExampleInterface exampleInterface) {
this.exampleInterface = exampleInterface;
}
public ExampleInterface getExampleInterface() {
return this.exampleInterface;
}
}
public class AbstractClassSubclass extends AbstractClass {
//Instead of the interface itself, I provide my constructor it's implementation
public AbstractClassSubclass(ExampleInterfaceImplementation exampleInterfaceImpl) {
super(exampleInterfaceImpl);
}
}
public class TestClass {
private void testMethod() {
AbstractClassSubclass test = new AbstractClassSubclass(
new ExampleInterfaceImplementation()
);
//Would return ExampleInterface, instead of ExampleInterfaceImplementation
test.getExampleInterface();
}
}
Update
I believe I have fixed this using type parameters.
I'm sure I have tried it before but had a few problems...
Now it works perfectly.
I want to create a new instance depending on an object, where I have the super class variable. Is this somehow possible without implementing a getNew() function or without usage of an ugly if chain?
In other words: How to implement the following newSubClass(..) function without using the getNew() function?
public abstract class SuperClass {
abstract public SuperClass getNew();
}
public class SubClassA extends SuperClass {
#Override
public SuperClass getNew() {
return new SubClassA();
}
}
public class SubClassB extends SuperClass {
#Override
public SuperClass getNew() {
return new SubClassB();
}
}
private SuperClass newSubClass(SuperClass superClass) {
return superClass.getNew();
}
After having some time to think about and zv3dh's contribution I decided this second answer.
I'am getting now you want an new instance of an instance of a subclass' type of SuperClass without knowing the concrete sub-type at runtime.
For that you have "reflexion".
public abstract class A_SuperClass {
public A_SuperClass createNewFromSubclassType(A_SuperClass toCreateNewFrom) {
A_SuperClass result = null;
if (toCreateNewFrom != null) {
result = toCreateNewFrom.getClass().newInstance();
}
// just an example, add try .. catch and further detailed checks
return result;
}
}
public class SubClassA extends A_SuperClass {
}
public class SubClassB extends A_SuperClass {
}
If you search for "java reflexion" you will get lots of results here on SO and on the web.
Have a look at the "FactoryMethod" design pattern.
It is exactly what you are looking for: It does encapsulate the "new" operator.
However your example makes me wonder:
Your getNew() reimplements what the constructor would do anyway
Try something like this:
public abstract class SuperClass {
public SuperClass createSuperClass(object someParam) {
if (someParem == a) return new SubClassA();
if (someParem == b) return new SubClassB();
}
}
public class SubClassA extends SuperClass {
}
public class SubClassB extends SuperClass {
}
As you see you need some IF at some place ...
I am looking for a way to have, in an abstract method, the return type to be the one of the implementation calling the method.
In other terms, I would like to write something like that:
public class GenericClass {
public <T extends GenericClass> T returnMyself() {
return (T)this; // Compiler warning, unsafe cast
}
}
public class Implem1 extends GenericClass {}
public class Implem2 extends GenericClass {}
public class Main {
public static void main(String[] args) {
Implem1 implem1 = new Implem1();
Implem1 again1 = implem1.returnMyself(); // Works fine, the type is inferred by the type of again1, I think
Implem1 again2 = implem1.<Implem1>returnMyself(); // Works fine, the type is explicitly asked by <Implem1>
Implem2 again3 = implem1.returnMyself(); // Works fine while it shouldn't.
}
}
What I am looking for is a way to declare the method so that at compilation time, returnMyself() can only return the type of the implementation invoking it (in my example, implem1 is of type Implem1), and ensure the code invoking cannot mistake/mix the types.
I searched quite a lot but couldn't find my answer anywhere (some topics seem similar but want a more general case, not explicitly the type of the implementaion invoking the method).
Some answers were correct, but always implied to override the method in each Implementation class, which may be cumbersome and bug-prone on my side. I'm ideally looking for a method that i would have to write only once in the Abstract class.
Any help/answer appreciated :D
You can do it like this:
public class Parent {
public Parent returnMyself() {
return this;
}
}
public class Child extends Parent {
public Child returnMyself() {
return this;
}
}
This is no problem because if you store a Child instance in a Parent variable then you expect a Parent return type of returnMyself(). Even if it is actually a Child object, the Child returned by returnMyself() extends Parent so there you go.
Since you mention abstract in your problem description, how about follow a model similar to Java's Enum class, where the generic type is in the class definition?
public abstract class GenericClass<T extends GenericClass> {
public abstract T returnMyself();
}
public class Implem1 extends GenericClass<Implem1> {
#Override
public Implem1 returnMyself() {
return this;
}
}
public class Implem2 extends GenericClass<Implem2> {
#Override
public Implem2 returnMyself() {
return this;
}
}
public class Main {
public static void main(String[] args) {
Implem1 implem1 = new Implem1();
Implem1 again1 = implem1.returnMyself(); // Works fine
Implem1 again2 = implem1.returnMyself(); // Works fine
Implem2 again3 = implem1.returnMyself(); // Does not compile
}
}
Since you want to write these methods inside of subclasses, this appears to be possible. You can override a method and have a different return type as long as the new return type is an extension of the old one:
Can overridden methods differ in return type?
I have an abstract class that should implement a public field, this field is an interface or another abstract classe.
something like this:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extends GenericChild {
public int prop1=2;
}
Now i have another specialized class Container:
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
Java allow me to compile this, and i IMAGINE that the field child in SpecialContainer is automatically overloading the field child of the GenericContainer...
The questions are:
Am i right on this? The automatic 'overloading' of child will happen?
And, more important question, if i have another class like this:
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
test() will return 1 or 2? i mean the GenericContainer container field what prop1 will call, the generic or the special?
And what if the special prop1 was declared as String (yes java allow me to compile also in this case)?
Thanks!
In Java, data members/attributes are not polymorphic. Overloading means that a field will have a different value depending from which class it's accessed. The field in the subclass will hide the field in the super-class, but both exists. The fields are invoked based on reference types, while methods are used of actual object. You can try it yourself.
It's called, variable hiding/shadowing, for more details look on here
It isn't overriding anything, you're just hiding the original field at the current class scope. If you use a variable with the subtype you will still be able to access the original property. Example:
abstract class GenericContainer {
public GenericChild child;
}
abstract class GenericChild {
public int prop1=1 ;
}
class SpecialChild extends GenericChild {
public int prop1=2;
}
class SpecialContainer extends GenericContainer {
public SpecialChild child;
}
public class Main {
public static void main( String ... args ) {
GenericContainer container = new SpecialContainer();
container.child = new SpecialChild();
System.out.println( container.child.prop1 );
SpecialChild child = (SpecialChild) container.child;
System.out.println( child.prop1 );
}
}
This prints 1 and then 2.
From SpecialChild you would also be able to go up one level using super:
class SpecialChild extends GenericChild {
public int prop1=2;
public int getOriginalProp1() {
return super.prop1;
}
}
Regarding
....and i IMAGINE that the field "child" in SpecialContainer is automatically overloading the field 'child' of the GenericContainer...
No. Fields don't get overridden, only methods do.
This is one reason why use of (overridable) getter and setter methods are preferred to direct access to fields. Your fields should almost all be private.
As for your design, there's no need for your SpecialContainer class to have a SpecialChild field, but instead the SpecialChild object should be placed in the GenericChild field.
Why nobody is observing that program will throw NullPointerException.
subclass's field with same name will hide super class's field. There is no overriding with field. Overriding is only possible with methods.
Original Code by Author:
public abstract class GenericContainer {
public GenericChild child;
}
public abstract class GenericChild {
public int prop1=1;
}
public abstract class SpecialChild extend GenericChild {
public int prop1=2;
}
public abstract class SpecialContainer extends GenericContainer {
public SpecialChild child=new SpecialChild(); //PAY ATTENTION HERE!
}
public class ExternalClass {
public GenericContainer container=new SpecialContainer();
public int test() {
return container.child.prop1
}
}
Java allow me to compile this, and i IMAGINE that the field "child" in
SpecialContainer is automatically overloading the field 'child' of the
GenericContainer...
Firstly, Inheritence doesn't apply to variables. Fields(Insatnce variables) are not overridden in your sub-class.they are only visible in your subclass if they are marked with either public, protected or default.
To answer your question it maintains both instances. And depending on how you refer to the container (either through the abstract or the impl) determines which variable you are referring to.
public class Test {
public abstract class Container{
public Generic gen = new Generic();
}
public class ContainerImpl extends Container{
public GenericImpl gen = new GenericImpl();
}
public class Generic{
public int prop = 0;
}
public class GenericImpl extends Generic{
public int prop = 1;
}
public Test(){
Container c = new ContainerImpl();
System.out.println(c.gen.prop); // Outputs "0"
System.out.println(((ContainerImpl)c).gen.prop); // Output "1"
}
public static void main(String[] args) {
new Test();
}
}
The bigger question at hand is, why would you design something like this? I'm assuming you are asking from a theoretical perspective.
My 2 cents, this isn't great OO design. You would be better off making the public variables private and assigning their values through a constructor or property setter. As-is, it will lead to unexpected results in your code.
I have a basic question about generics in Java.
I have a class X which is instantiated by another class T. In every class T which will be used has a method called as methodOfT(). However, Java gives me compiler time error since it does not know obj and methodOfT().
public class X<T>
{
T obj;
public void methodOfX()
{
obj.methodOfT();
}
}
In order to avoid this problem, what I did is I defined another class XSuper. And every class now which wants to instantiate X will extend this XSuper class. This removes the compile time error and allows me to achieve what I want.
public abstract class XSuper
{
public abstract void methodOfT();
}
public class UserOfX extends XSuper
{
X<UserOfX> objX = new X<UserOfX>();
public void methodOfT()
{
}
}
However, I want to know the cleaner way of doing this thing. Since I want to derive class UserOfX from another Class. Another Problem is that I want to define methodOfT() method as -
public methodOfT(T objOfT)
{
}
In this case, the above solution fails. Could someone help.
public class X<T>
{
T obj;
public void methodOfX()
{
obj.methodOfT();
}
}
The compiler doesn't know what T is so it is evaluated as Object. Object does not have a methodOfT method, so compilation fails. Here's how to solve that:
public interface SomeInterface{
void methodOfT();
}
public class X<T extends SomeInterface>
{
T obj;
public void methodOfX()
{
obj.methodOfT();
}
}
In this case, the compiler knows that the supplied T will implement the interface SomeInterface and hence have the method methodOfT. (You can also use classes instead of interfaces, but that's less elegant)
Given your additional requirements, we're going t have to change this code some more:
public interface SomeInterface<X>{
void methodOfT(X object);
}
public class X<T1, T2 extends SomeInterface<T1>>
{
T1 obj1;
T2 obj2;
public void methodOfX()
{
obj2.methodOfT(obj1);
}
}