generic factory method convention - java

Let me say there is an abstract class which looks like
abstract class Parent<V> {
protected static <T extends Parent<V>, V> T newInstance(
final Class<T> type, final V value) {
// ...
}
}
Within following Child class
class Child extends Parent<XXX> {
public static Child newInstance1(final XXX value) {
// ...
}
public static Parent<XXX> newInstance2(final XXX value) {
// ...
}
}
Which one is preferable? newInstance1 or newInstancw2?

It actually depends on the scenario in which you are you using the newInstance(). In most general cases:
Since Child is implementing newInstance(), According to me
protected static Child newInstance()
{
// ...
}
would be more appropriate.

Usually, factory method defined inside some class returns instance of this particular class, so it should be:
public class Foo ...
{
public static Foo newInstance ()
{
...
}
}
regardless of what class this class extends and what interfaces it implements.

Related

Any way to specify a java generic type variable that extends any one of multiple classes?

So suppose I have 2 classes:
public class A
{
public void
f()
{
}
}
public class B
{
public void
f()
{
}
}
I would like to write a generic static method that could call f when passed an instance of A or B. I tried:
public class C
{
public static <T extends A & B> void
g(T t)
{
t.f();
}
public static void main(String[] args)
{
A a = new A();
g(a);
}
}
But the compiler claims A is not a valid substitute for "T extends A & B", which I assume is because T must extend BOTH A and B, which obviously A does not. I could not find a way to specify something like "T extends A OR B". Is something like this not achievable? I am a java neophyte, so any help with this would be appreciated.
You can only specify one generic type. Use interfaces instead.
An interface specifies a certain set of methods, each member of it has to have. A class can implement multiple interfaces.
In your example, I would define an interface with the method f():
public interface MyInterface {
void f();
}
Let A and B implement the interface:
public class A implements MyInterface
{
#Override
public void f() {
// ...
}
}
public class B implements MyInterface
{
#Override
public void f() {
// ...
}
}
Then you can just specify the interface as type of the argument for your method:
public static void g(MyInterface obj)
{
obj.f();
}
For more detail on interfaces, check the Java documentation: What Is an Interface?

C++ Templates & Inheritance in Java

I have the following classes in C++
ParentClass
{
virtual int MyMethod();
}
class ExistingOne : ParentClass {...}
class ExistingTwo : ParentClass {...}
Now I would like to create a class that can extend either of the Existing classes and override a couple of their methods plus call a method in the Existing class under some conditions.
In C++ this is done using the following:
template< class BaseTemplate >
class MyClass : public BaseTemplate
{
int MyMethod()
{
DoSomething();
return BaseTemplate::MyMethod();
}
}
How is this done in Java?
So far I have
public abstract class ParentClass
{
public abstract int MyMethod();
}
public class ExistingOne extends ParentClass {...}
public class ExistingTwo extends ParentClass {...}
public class MyClass<T extends ParentClass>
{
public int MyMethod()
{
DoSomething();
return T.MyMethod(); //MyMethod must be statically defined?
}
}
Oh and lastly, I cannot modify the "Existing" or Parent class.
So is this the correct approach? How do I solve the static requirement?
In the C++ class definition, MyClass extends BaseTemplate. In the Java example, MyClass doesn't extend ParentClass, thus getting the expected problem.
In Java, just change the definition to:
public class MyClass<T extends ParentClass> extends ParentClass {
#Override
public int MyMethod() {
DoSomething();
return super.MyMethod();
}
}
Since MyMethod is abstract in ParentClass, this gives a compiler error. Instead, you would need to call MyMethod from an instance of ParentClass. This can be fixed by having a field T t inside MyClass:
public class MyClass<T extends ParentClass> extends ParentClass {
T t;
public MyClass(T t) {
this.t = t;
}
#Override
public int MyMethod() {
DoSomething();
return t.MyMethod();
}
}
Otherwise, using generics and extending ParentClass here won't have any sense at all.

How to instantiate a generic class

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.

How to access parent method from field?

I have tree classes.
class MyObject{
public void DoSomething()
{
here I need to call method add from class base.
}
}
class base
{
protected final void add(){}
}
class extended extends base {
private MyObject pObject = new MyObject();
...
{
pObject.DoSomething();
}
}
I could have created class for each variation that extends class extended, but the type what I need to use becomes available only after class extended is already initiated.
How do I call base.add() from MyObject inner method?
You can do it in a couple of ways:
Have a reference of your extended class in MyObject class. When you instantiate MyObject variable in extended class, pass it the reference of extended.
Something like this:
class MyObject{
private base baseObj;
public MyObject(base baseObj){
this.baseObj = baseObj;
}
public void DoSomething()
{
//here I need to call method add from class base.
//use baseObj to call the methods
}
}
class base
{
protected final void add(){}
}
class extended extends base {
private MyObject pObject;
...
public extended(){
pObject = new MyObject(this);
}
{
pObject.DoSomething();
}
}
Declare the methods in base class static. This way you can call the methods without requiring an instance of the base class.
Something like this:
class MyObject{
public void DoSomething()
{
//here I need to call method add from class base.
//call like this
base.add();
}
}
class base
{
protected static final void add(){}
}
class extended extends base {
private MyObject pObject;
...
public extended(){
pObject = new MyObject(this);
}
{
pObject.DoSomething();
}
}
One more thing: This is off-topic, but you might want to read about Java Naming Conventions. Having class names start with lowercase is something that you wouldn't find in the naming conventions.
dummy code like this:
class MyObject{
public void DoSomething(Base base)
{
base.add();
}
}
class extended extends base {
private MyObject pObject = new MyObject();
...
{
pObject.DoSomething(this);
}
}

Extending an abstract constructor?

So I've come across a bit of a snag in some code that I'm working with. Essentially I have the following three tidbits of code:
Abstract class:
public abstract class TestParent {
int size;
public TestParent(int i){
size = i;
}
}
Child Class:
public class TestChild extends TestParent{
public void mult(){
System.out.println(this.size * 5);
}
}
Implementation:
public class TestTest {
public static void main(String args[]) {
TestChild Test = new TestChild(2);
Test.mult();
}
}
Consider the following case of abstract class and extends implementation.
https://stackoverflow.com/a/260755/1071979
abstract class Product {
int multiplyBy;
public Product( int multiplyBy ) {
this.multiplyBy = multiplyBy;
}
public int mutiply(int val) {
return muliplyBy * val;
}
}
class TimesTwo extends Product {
public TimesTwo() {
super(2);
}
}
class TimesWhat extends Product {
public TimesWhat(int what) {
super(what);
}
}
The superclass Product is abstract and has a constructor. The concrete class TimesTwo has a default constructor that just hardcodes the value 2. The concrete class TimesWhat has a constructor that allows the caller to specify the value.
NOTE: As there is no default (or no-arg) constructor in the parent abstract class the constructor used in subclasses must be specified.
Abstract constructors will frequently be used to enforce class constraints or invariants such as the minimum fields required to setup the class.
public class TestChild extends TestParent{
public TestChild(int i){
super(i); // Call to the parent's constructor.
}
public void mult(){
System.out.println(super.size * 5);
}
}
Use super to call parent (TestParent.TestParent(int)) constructor:
public class TestChild extends TestParent{
public TestChild(int i) {
super(i);
}
//...
}
or if you want to use some constant:
public TestChild() {
super(42);
}
Note that there is no such thing as abstract constructor in Java. Essentially there is only one constructor in TestParent which must be called before calling TestChild constructor.
Also note that super() must always be the first statement.
When you have explicit constructor defined in super class and no constructor without arguments defined, your child class should explicitly call the super class constructor.
public class TestChild extends TestParent{
TestChild ()
{
super(5);
}
}
or, if you don't want call super class constructor with parameters, you need to add constructor with no arguments in super class.
public abstract class TestParent {
int size;
public TestParent(){
}
public TestParent(int i){
size = i;
}
}
You code wont compile because your base class does not have a default constructor. Either you need to provide it in base class or you need to provide parameterized constructor in derived class and invoke super.
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i * 2);
}
}
This code would use the double of i. This is an overriding, though i'm not sure what you want to ask.
Other solution:
public class TestChild extends TestParent{
public TestChild (int i)
{
super(i);
this.size = 105;
}
}
For this solution, size must be protected or public.

Categories

Resources