inheritance misunderstanding

G

glunk

I have a class called PdfWriter. Its constructor has several params. It has
a method setFields which must be overloaded.

I have a subclass called ConsolidationApplicationPdfWriter. What I could do
is have the constructor of this class have the same params as the super
class.

public ConsolidationApplicationPdfWriter (String templateName, boolean
stength128Bit, String userPassword, char acrobatVersion)

then call

super (templateName, strength128Bit, userPassword, acrobatVersion)

These values are stored in an XML file for each Application. So within
ConsolidationApplicationPdfWriter, I would like to get the values from the
XML file, then call super() with the values I have gotten.

But I cannot, of course, because super() has to be the first command in a
constructor whcih uses it.

This is where I get confused. How can I give the values for the parameters
in the super constructor? There is no need for it to be a mutable object
other than this. But the only thing I can think of to do is have a zero
param constructor and then use setters. But I do not want to do this since I
am sure I am just misunderstanding how to implement inheritence.

Thanks for your help. You guys have already helped me understand a ton. I
appreciate it.

S
 
M

Michael Borgwardt

glunk said:
These values are stored in an XML file for each Application. So within
ConsolidationApplicationPdfWriter, I would like to get the values from the
XML file, then call super() with the values I have gotten.

But I cannot, of course, because super() has to be the first command in a
constructor whcih uses it.

This is where I get confused. How can I give the values for the parameters
in the super constructor? There is no need for it to be a mutable object
other than this.

Use a static factory method that calls a private constructor which takes all
the parameters.
 
M

Michiel Konstapel

I have a class called PdfWriter. Its constructor has several params. It
has
a method setFields which must be overloaded.

I have a subclass called ConsolidationApplicationPdfWriter. What I could
do
is have the constructor of this class have the same params as the super
class.

public ConsolidationApplicationPdfWriter (String templateName, boolean
stength128Bit, String userPassword, char acrobatVersion)

then call

super (templateName, strength128Bit, userPassword, acrobatVersion)

These values are stored in an XML file for each Application. So within
ConsolidationApplicationPdfWriter, I would like to get the values from
the
XML file, then call super() with the values I have gotten.

But I cannot, of course, because super() has to be the first command in a
constructor whcih uses it.

This is where I get confused. How can I give the values for the
parameters
in the super constructor? There is no need for it to be a mutable object
other than this. But the only thing I can think of to do is have a zero
param constructor and then use setters. But I do not want to do this
since I
am sure I am just misunderstanding how to implement inheritence.

You can call
super(getTemplateName(), getStrength128(), ...);
where getTemplateName() and the rest are static methods (you can't call
instance methods at that point) that extract the appropriate values from
the XML file to pass to the superclass constructor.
HTH,
Michiel
 
G

glunk

Michiel Konstapel said:
You can call
super(getTemplateName(), getStrength128(), ...);
where getTemplateName() and the rest are static methods (you can't call
instance methods at that point) that extract the appropriate values from
the XML file to pass to the superclass constructor.
HTH,
Michiel


COOL! Is this answer the same as the answer from Michael B above? That is
are getTemplateName() etc.. static factory methods? Just want to understand
what is going on!

Thanks!
 
C

Chris Smith

glunk said:
COOL! Is this answer the same as the answer from Michael B above? That is
are getTemplateName() etc.. static factory methods? Just want to understand
what is going on!

No, they are different. Michael (with an a) suggested:

class SomeClass
{
private SomeClass(int arg1, int arg2)
{
super(arg1, arg2)
}

public static SomeClass createInstance(File xmlFile)
{
// Read the XML file
int arg1 = ...;
int arg2 = ...;

return new SomeClass(arg1, arg2);
}
}

But Michiel (with an i) suggested:

class SomeClass
{
public SomeClass(File xmlFile)
{
super(getArg1(xmlFile), getArg2(xmlFile));
}

private static int getArg1(File xmlFile)
{
// Read the XML file
return ...;
}

private static int getArg2(File xmlFile)
{
// Read the XML file
return ...;
}
}

Both make use of static methods, but the exposed interface is different.
In Michael's answer, the static method is public and the constructor is
private. In Michiel's answer, the constructor is public and the static
methods are private. So Michiel's answer requires no modification to
the code that creates the object, but Michael's answer requires that the
code to create the object is modified to look like:

SomeClass x = SomeClass.createInstance(xmlFile);

On the other hand, the static factory method makes up for the change to
the client interface in that it's much more flexible in implementation;
you don't need to either parse the XML file twice or implement some kind
of complex caching scheme, as you would with the static helpers.

Both will work. Which you choose is up to you.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
G

glunk

Chris Smith said:
No, they are different. Michael (with an a) suggested:

class SomeClass
{
private SomeClass(int arg1, int arg2)
{
super(arg1, arg2)
}

public static SomeClass createInstance(File xmlFile)
{
// Read the XML file
int arg1 = ...;
int arg2 = ...;

return new SomeClass(arg1, arg2);
}
}

But Michiel (with an i) suggested:

class SomeClass
{
public SomeClass(File xmlFile)
{
super(getArg1(xmlFile), getArg2(xmlFile));
}

private static int getArg1(File xmlFile)
{
// Read the XML file
return ...;
}

private static int getArg2(File xmlFile)
{
// Read the XML file
return ...;
}
}

Both make use of static methods, but the exposed interface is different.
In Michael's answer, the static method is public and the constructor is
private. In Michiel's answer, the constructor is public and the static
methods are private. So Michiel's answer requires no modification to
the code that creates the object, but Michael's answer requires that the
code to create the object is modified to look like:

SomeClass x = SomeClass.createInstance(xmlFile);

On the other hand, the static factory method makes up for the change to
the client interface in that it's much more flexible in implementation;
you don't need to either parse the XML file twice or implement some kind
of complex caching scheme, as you would with the static helpers.

Both will work. Which you choose is up to you.


Thanks all of you. Understanding is happening one small step at a time!

S
 
D

Dale King

Hello, Chris Smith !
You said:
But Michiel (with an i) suggested:

class SomeClass
{
public SomeClass(File xmlFile)
{
super(getArg1(xmlFile), getArg2(xmlFile));
}

private static int getArg1(File xmlFile)
{
// Read the XML file
return ...;
}

private static int getArg2(File xmlFile)
{
// Read the XML file
return ...;
}
}

And another variation on this theme is that you create a simple
class that contains all the parameters as fields or better yet an
interface that defines getter methods for all the fields. You
have a constructor that takes one of these object instances as
its parameter and makes the super call extracting the data from
the object.

Then you can define another class that implements this interface
and its constructor takes a parameter of an XML file. This allows
you to create other variations that get the data from other data
sources, e.g. a properties file, a HashMap, parsed from command
line arguments. And these new type of data sources can be added
without changing the original class.

This may be overkill for your design, but your design doesn't
seem right since you are requiring that the class that does the
writing also know about reading an XML file to get its
parameters. That is too tightly coupled (or is that low
cohesion?).

So something like the following: (note I shortened your class
name because it seems to me that ConsolidationApplication is
really information that belongs as part of the package not the
class name)

public class PdfWriter
{
public interface Params
{
String getTemplateName();
boolean isStrength128Bit();
String getUserPassword();
int getAcrobatVersion();
}
public PdfWriter( String templateName, boolean
strength128Bit, String userPassword, char acrobatVersion)
{ ... }

public PdfWriter( Parms params )
{
this( params.getTemplateName(),
params.isStrength128Bit(),
params.getUserPassword(),
params.getAcrobatVersion());
}
}

The conversion from an XML file to PdfWriter.Params is then done
in another class that takes the XML file as a parameter to the
constructor and implements the PdfWriter.Params intrface.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top