Template method pattern in Java ???

Q

qazmlp

Can't Template method pattern be used in Java?

I just wanted to translate the following C++ code:
class ClassBase
{
// Other members
public:
void setData(const std::vector<std::string>& dataVec);

private:
virtual void doSetData(const std::vector<std::string>& dataVec) = 0;
};

into this Java code:
public abstract class ClassBase
{
// Other members
public void setData( final Vector dataVec) { }
private abstract void doSetData( Vector dataVec );
}

But, the Java compiler reports the following error:
ClassBase.java:11: Abstract methods can't be private: void doSetData(Vector)
private abstract void doSetData( Vector dataVec );

Why is this so? Then, what is the alternative for my above C++ class in Java?

Thanks!
 
C

Christophe Vanfleteren

qazmlp said:
Can't Template method pattern be used in Java?

I just wanted to translate the following C++ code:
class ClassBase
{
// Other members
public:
void setData(const std::vector<std::string>& dataVec);

private:
virtual void doSetData(const std::vector<std::string>& dataVec) = 0;
};

into this Java code:
public abstract class ClassBase
{
// Other members
public void setData( final Vector dataVec) { }
private abstract void doSetData( Vector dataVec );
}

But, the Java compiler reports the following error:
ClassBase.java:11: Abstract methods can't be private: void
doSetData(Vector)
private abstract void doSetData( Vector dataVec );

Why is this so? Then, what is the alternative for my above C++ class in
Java?

Thanks!

Of course you can do that. But the problem with your implementation is that
you've made doSetData() private, so that would mean that it is not visible
to any subclass. At the same time, you're declaring doSetData() to be
abstract, meaning that some subclass will have to implement this method,
but now it can't, since you made it private. This is exactly what the
compiler is telling you.

So just define doSetData() to be protected, so subclasses can acces and
implement that method.

Look in the java tutorial for the different acces modifiers you can use and
the differences between them.
 
R

Robert C. Martin

Can't Template method pattern be used in Java?

I just wanted to translate the following C++ code:
class ClassBase
{
// Other members
public:
void setData(const std::vector<std::string>& dataVec);

private:
virtual void doSetData(const std::vector<std::string>& dataVec) = 0;
};

into this Java code:
public abstract class ClassBase
{
// Other members
public void setData( final Vector dataVec) { }
private abstract void doSetData( Vector dataVec );
}

But, the Java compiler reports the following error:
ClassBase.java:11: Abstract methods can't be private: void doSetData(Vector)
private abstract void doSetData( Vector dataVec );

Why is this so? Then, what is the alternative for my above C++ class in Java?

Java does not allow you to override a private method. C++ does. In
your case you'll have ot make the doSetdata method protected. (sigh)
 
D

Dave Harris

ClassBase.java:11: Abstract methods can't be private

Why is this so?

Access control is not orthogonal to polymorphism in Java. Private methods
are not only not abstract, they cannot even be virtual. The main benefit
is that private methods really are private in Java; they can't be
interfered with by other classes. In C++ they can be. Eg:

class Base {
private:
virtual void method();
};

class Derived: Base {
private:
void method();
};


In C++ Derived::method is an override of Base::method, despite it being
private and not declared as virtual. This means the author of Derived has
to know about Base's private methods when he is choosing the names of his
own private methods. It is one of the two ways that "private" is leaky in
C++. It would horrify many Java users.

Then, what is the alternative for my above C++ class in Java?

Don't declare the method to be private.

-- Dave Harris, Nottingham, UK
 
T

TT \(Tom Tempelaere\)

qazmlp said:
Can't Template method pattern be used in Java?

I just wanted to translate the following C++ code:
class ClassBase
{
// Other members
public:
void setData(const std::vector<std::string>& dataVec);

private:
virtual void doSetData(const std::vector<std::string>& dataVec) = 0;
};

into this Java code:
public abstract class ClassBase
{
// Other members
public void setData( final Vector dataVec) { }
private abstract void doSetData( Vector dataVec );
}

But, the Java compiler reports the following error:
ClassBase.java:11: Abstract methods can't be private: void doSetData(Vector)
private abstract void doSetData( Vector dataVec );

Why is this so? Then, what is the alternative for my above C++ class in Java?

Thanks!

You can't override private methods in Java. The following comes close to the
template pattern.

public abstract class BaseCls
{
// ...
public final void setData(Vector data) {
// pre-ops
doSetData(data);
// post-ops
}
protected abstract void doSetData(Vector data);
}

public final class ConcreteCls extends BaseCls
{
// ...
protected void doSetData(Vector data) {
// concrete implementation
}
}
 
R

Robert C. Martin

ClassBase.java:11: Abstract methods can't be private

Why is this so?

Access control is not orthogonal to polymorphism in Java. Private methods
are not only not abstract, they cannot even be virtual. The main benefit
is that private methods really are private in Java; they can't be
interfered with by other classes. In C++ they can be. Eg:

class Base {
private:
virtual void method();
};

class Derived: Base {
private:
void method();
};


In C++ Derived::method is an override of Base::method, despite it being
private and not declared as virtual. This means the author of Derived has
to know about Base's private methods when he is choosing the names of his
own private methods. It is one of the two ways that "private" is leaky in
C++. It would horrify many Java users.[/QUOTE]

I prefer the C++ convention to the Java one -- probably because it's
what I learned first. I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.
 
D

David Roden

Robert said:
[...] I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.

Then why do you want to declare it in an interface?
 
R

Robert C. Martin

Robert said:
[...] I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.

Then why do you want to declare it in an interface?

Not an interface, an abstract class.

class Application {
public:
void Run() {
Init();
while (!done)
Idle();
Cleanup();
}

protected:
bool done;

private:
virtual void Init() = 0;
virtual void Idle() = 0;
virtual void Cleanup() = 0;
};
 
A

Avner Ben

David said:
Robert C. Martin wrote:

[...] I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.


Then why do you want to declare it in an interface?

I agree with you.

Robert Martin is apparently on a methodical collision course here. If he
says that he knows what the method is doing (i.e. invoking another
method), then he is practically confessing that it is not an interface!

Please, correct my reasoning if it is wrong!

Avner.
 
S

Steven Wurster

Avner Ben said:
David said:
Robert said:
[...] I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.

Then why do you want to declare it in an interface?

I agree with you.

Robert Martin is apparently on a methodical collision course here. If he
says that he knows what the method is doing (i.e. invoking another
method), then he is practically confessing that it is not an interface!

Please, correct my reasoning if it is wrong!

It is wrong. Don't think like a Java programmer for this one. I
realize this is a Java thread, but RCM was using C++. See his reply
to the above post.

Note that only in Java does the term interface have that special
meaning of a class with only abstract, or sometimes called deferred,
routines. But that's not what an interface really is. The interface
is the collection of all of the routines in a class and their
contracts (if any). A Java interface is what the rest of the O-O
world tends to call a purely abstract or purely deferred class.

But as shown by RCM's example, and many others I can think of, having
an abstract class that contains non-abstract routines is quite useful.
In fact, it's a regular occurrence.

Steve
 
A

Avner Ben

Steven said:
It is wrong. Don't think like a Java programmer for this one. I
realize this is a Java thread, but RCM was using C++. See his reply
to the above post.

Note that only in Java does the term interface have that special
meaning of a class with only abstract, or sometimes called deferred,
routines. But that's not what an interface really is. The interface
is the collection of all of the routines in a class and their
contracts (if any). A Java interface is what the rest of the O-O
world tends to call a purely abstract or purely deferred class.

So it is in C#, too!

Even according to your version, the purpose of interface is to specify
the available message selectors (function names) and their usage
contract, and never to disclose the methods themselves (function body).

By saying that he needs a private message selector in the interface
because it is being used by the method behind a non-private message
selector, Robert Martin effectively violates the definition of that
class as interface.

Generally, by saying that the method hidden behind a message selector is
a template method, one exposes the method. Therefore, An interface, by
definition, cannot contain a template method AS A REQUIREMENT (or for
that purpose, any pattern or idiom that involves knowing what is inside
the method).

Such patterns and idioms as template method and rectangular inheritance
of association belong in the realm of abstract base classes, because
they require implementation, as well as interface!

Avner.

Avner.
 
D

David Roden

Robert said:
[...] I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.
Then why do you want to declare it in an interface?
Not an interface, an abstract class.

Well, yes, that was quite what I meant. :)

class Application {
public:
void Run() {
Init();
while (!done)
Idle();
Cleanup();
}

protected:
bool done;

private:
virtual void Init() = 0;
virtual void Idle() = 0;
virtual void Cleanup() = 0;
};

In Java you can't override private methods. That means that you can
declare an Init() method in a derived class, but the base class won't be
calling it.

Summa sumarum this means that what you are trying to do will not work
this way in Java. You have two possibilities:

a) expose the methods to the derived class by making them protected (or
public), or

b) simply implement them as private methodes.

Both things at the same is simply not possible in Java at this time (and
I doubt that's going to change).
 
S

Steven Wurster

Avner Ben said:
So it is in C#, too!

Perhaps it does. Doesn't mean it's semantically correct.

Even according to your version, the purpose of interface is to specify
the available message selectors (function names) and their usage
contract, and never to disclose the methods themselves (function body).

The contents of the routines are never disclosed, that is correct.

By saying that he needs a private message selector in the interface
because it is being used by the method behind a non-private message
selector, Robert Martin effectively violates the definition of that
class as interface.

No, not really. The client, and that's who we're writing the class
for, doesn't see anything but the interface. And nowhere did RCM
mention that his routine would be calling other, possibly private,
possibly abstract, routines. That's in the implementation, and
looking there violates encapsulation. The interface is still there
for the client to code against.

Therefore, An interface, by definition, cannot contain a template method AS
A REQUIREMENT (or for that purpose, any pattern or idiom that involves
knowing what is inside the method).

Knowing what's inside a routine does violate encapsulation. But the
template method doesn't have to be explicitly spelled out to clients.
It's an implementation thing that is of concern to the programmers of
descendent classes.

And, again, check your definition of interface. An interface is all
of the publicly available routines of a class without their
implementations, if any. What's behind those, and how that works, is
irrelevant to a client.

Such patterns and idioms as template method and rectangular inheritance
of association belong in the realm of abstract base classes, because
they require implementation, as well as interface!

I'm not sure what you mean by rectangular inheritance of association.
I think in terms of clients & suppliers and ancestors & descendants.
Anything else makes things more complex than they need to be. Plus
I'm not sure how you say they belong in the abstract realm when they
require implementation. Doesn't that go against your previous
comments, or am I missing something?

Steve
 
U

Universe

David Roden said:
Robert said:
[...] I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.
Then why do you want to declare it in an interface?
Not an interface, an abstract class.

Well, yes, that was quite what I meant. :)

class Application {
public:
void Run() {
Init();
while (!done)
Idle();
Cleanup();
}

protected:
bool done;

private:
virtual void Init() = 0;
virtual void Idle() = 0;
virtual void Cleanup() = 0;
};

In Java you can't override private methods. That means that you can
declare an Init() method in a derived class, but the base class won't be
calling it.

As far as understand the same is true with C++.

So I really do not understand why, how, RCM would propose this solution with
private pure virtual methods.

Even a Public visibility derived child can not define or access a parent's
private members or functions-pure virtual or not.

Now this would work wonderfully in C++ if the pure virtuals were given
'Protected' visibility. Then only a Public visibility derived child could
define and call the pure virtuals. One could also use a pointer of base
class static type to invoke a child's definition of the pure virtuals.

Elliott
 
R

Robert C. Martin

So it is in C#, too!

True. But then C# is just Java with some tokens changed.
Even according to your version, the purpose of interface is to specify
the available message selectors (function names) and their usage
contract, and never to disclose the methods themselves (function body).

What if the messages are never meant to be called by functions other
than those defined in the base class; and yet the need to be
implemented in derived classes? The base class is acting as it's own
interface... This is the essence of the TemplateMethod pattern.
By saying that he needs a private message selector in the interface
because it is being used by the method behind a non-private message
selector, Robert Martin effectively violates the definition of that
class as interface.

It's not an interface for anyone else, just for the functions of the
class itself.
 
F

Frank Schmitt

Universe said:
As far as understand the same is true with C++.

No, it isn't. Just try it:

#include <iostream>

class Base {
public:
void Init() {
std::cout << getClassID() << "\n";
}
private:
virtual int getClassID() const = 0;
};

class Derived: public Base {
private:
virtual int getClassID() const {
return 1;
}
};

int main() {
Base* b = new Derived;
b->Init();
return 0;
}

So I really do not understand why, how, RCM would propose this solution with
private pure virtual methods.

Even a Public visibility derived child can not define or access a parent's
private members or functions-pure virtual or not.

You misunderstood the Template Method Pattern - the descendant doesn't have to
access a parent's private members.

kind regards
frank
 
S

Steven Wurster

Universe said:
As far as understand the same is true with C++.

So I really do not understand why, how, RCM would propose this solution with
private pure virtual methods.

You can override private virtual methods in descendants in C++. The
virtual qualifier means dynamic binding, so the exporting and
inheritance rules are slightly different. I had a reference to this
at one point, but now I can't find it. I tested it, though, and it
does work.

Steve
 
D

Dave Harris

I prefer the C++ convention to the Java one -- probably because it's
what I learned first. I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it.

Except that if the private virtual pure function is in a derived class,
the base class may also be able to call it.

I can see the advantages of both schemes. I would be happier with the C++
approach if it also had a way of saying whether a function was expected to
override an inherited one. (I think C# has this.) Then at least accidental
overrides could be detected at compile time.


-- Dave Harris, Nottingham, UK
 
A

Avner Ben

Steven Wurster wrote:

No, not really. The client, and that's who we're writing the class
for, doesn't see anything but the interface. And nowhere did RCM
mention that his routine would be calling other, possibly private,
possibly abstract, routines. That's in the implementation, and
looking there violates encapsulation. The interface is still there
for the client to code against.

Yes he did say that: <quote>I like being able to declare a private pure
virtual function. What is says to me is that nobody but the base
should call it. said:
Knowing what's inside a routine does violate encapsulation. But the
template method doesn't have to be explicitly spelled out to clients.
It's an implementation thing that is of concern to the programmers of
descendent classes.

A contradiction of terms just the same, since no OOPL that I know of
allows you to do that (declare an interface with a hidden part). And
they are right. had they, they would be violating the very notion of
interface.
And, again, check your definition of interface. An interface is all
of the publicly available routines of a class without their
implementations, if any. What's behind those, and how that works, is
irrelevant to a client.

Make up your mind, please! does it or does not it have private,
non-disclosed, internal-use-only part?
I'm not sure what you mean by rectangular inheritance of association.

Abstract container defines the ability to contain and navigate through
many base objects. Concrete container knows what to do with concrete
objects, limiting the scope of the containment and navigation skills
inherited. The base and derived classes must work in team to ensure that
the limited-edition container is not contaminated with unwanted
objects. E.g., the GOF version of the observer pattern.
Since the base container defines - or at least, promises -
implementation as well as interface, then it is an abstract base class
and not an interface.
To summarize the point: an interface states what may be done; and
abstract base class also lays the foundation for doing it. Therefore,
the presence of rectangular inheritance of association or template
method in a base class make it an abstract base class and never an
interface.
<snip/> Plus
I'm not sure how you say they belong in the abstract realm when they
require implementation. Doesn't that go against your previous
comments, or am I missing something?

See above. An abstract base class does productive work - it does have
methods (in addition to message selectors). However, there is at least
one method that it forces its derivations to implement. This is what
makes it abstract. When it has no implementation at all, it may - and
had better - also be called "interface".

Avner.
 
A

Avner Ben

Robert said:
True. But then C# is just Java with some tokens changed.

I must disagree! Both Java and C# share the same origin (Smalltalk
inside, like C++ outside). However, C# owes more to pure OOPL research
and to dynamic languages like Python and, little than I can see, to
Java. On the contrary, for all I see, Java 1.5 is borrowing ideas from C#.
What if the messages are never meant to be called by functions other
than those defined in the base class; and yet the need to be
implemented in derived classes? The base class is acting as it's own
interface... This is the essence of the TemplateMethod pattern.

Agreed. Incidentally, this also violates the very notion of interface. I
repeat my position: If you know what the implementation of the
"interface" is, what it is doing inside (e.g., relying on an internal
method), then it ceases being an interface.
It's not an interface for anyone else, just for the functions of the
class itself.

I am hearing about private interfaces for the first time here. Is this a
new concept?

Avner.
 

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,596
Members
45,130
Latest member
MitchellTe
Top