what are the other ways to prevent a class from being subclassed. one way is to declare the class fi

  • Thread starter srinivas.veeranki
  • Start date
S

srinivas.veeranki

Hi All,

what are the other ways to prevent a class from being subclassed. one
way is to declare the class final.


Thanks

Srinivas
 
N

NullBock

You could throw an exception in the ctor, if it's being called on a
derived class:

class NoExtend {
public NoExtend() {
if (this.getClass() != NoExtend.class) {
throw new RuntimeException();
}
}
}

Or you could have a private ctor, with a public factory method:

class NoExtend {
private NoExtend() {
}

public static NoExtend create() {
return new NoExtend();
}
}

Those are two methods that come to mind...

Walter

----
Walter Gildersleeve
Freiburg, Germany

______________________________________________________
http://linkfrog.net
URL Shortening
Free and easy, small and green.
 
R

Roedy Green

what are the other ways to prevent a class from being subclassed. one
way is to declare the class final.

Why do you want to know another method? What is the matter with
declaring a class final?
 
E

EJP

Roedy said:
Doing that and not declaring the class final is what I call
"tantalising"

Not as tantalising as all that. You certainly don't have to wait until
'bebug time' to discover it as your glossary claims. The first
compilation will tell you. More generally you might declare the ctors as
package-private: would you describe that as 'tantalising'? inside a
sealed package? where you do draw the line?
 
R

Roedy Green

Not as tantalising as all that. You certainly don't have to wait until
'bebug time' to discover it as your glossary claims.


If it is an alternate implementation, you won't find out till run
time, or maybe never. The compile will be quite happy so long as your
method signatures you use match.

If it a totally unrelated class you will find out at compile time, and
you will likely be puzzled all the heck why it does not recognise your
methods.
 
E

EJP

Roedy said:
If it is an alternate implementation, you won't find out till run
time, or maybe never. The compile will be quite happy so long as your
method signatures you use match.

You will definitely find out, because of super() being private, but
actually we seem to be getting a fair way off the point here. A
replacement class newly marked as 'final' will also have some
'tantalizing' behaviour at runtime.
If it a totally unrelated class you will find out at compile time, and
you will likely be puzzled all the heck why it does not recognise your
methods.

My compiler complains about not being able to call super() because it is
private. This doesn't puzzle me. I don't know what is meant by 'not
recognizing your methods'.

I was really only answering the OP's question for completeness, not to
advocate any particular style, but the use of this pattern e.g. for
factory or singleton classes seems perfectly legitimate to me, and not
'tantalising'.
 
R

Roedy Green

You will definitely find out, because of super() being private, but
actually we seem to be getting a fair way off the point here. A
replacement class newly marked as 'final' will also have some
'tantalizing' behaviour at runtime.

I am confused since we have been discussing vaguely related issues in
different threads.

1. if you use wildcard imports you can get he wrong class and not
notice even at run time. All that has to happen is the signatures to
match of the methods you actually use.

2. if someone makes all constructors private but leaves the class
itself public, someone researching his problem will note the class is
not final and base a design on that. when he actually comes to do the
work of extending the class he finds out when he compiles he is in
trouble since the super constructor is private. He has wasted time
designing and writing his class. That is tantalising. Shoot the
asshole who pulled this childish stunt.
 
N

NullBock

The problems you mention are pretty far-fetched, and would be caught
early in production, in any case. Indeed, you'd have to give me an
example to show that problem 1) could happen without compile-time
errors--normally you'd get a ambiguity error:

import java.util.*;
import javax.swing.*;

class MyTimer extends Timer {//won't compile
}

As has been mentioned, non-final, non-inheritable classes are useful in
certain design patterns, including singletons, abstract factories and
prototypes.


----
Walter Gildersleeve
Freiburg, Germany

______________________________________________________
http://linkfrog.net
URL Shortening
Free and easy, small and green.
 
R

Ranganath Kini

Roedy said:
2. if someone makes all constructors private but leaves the class
itself public, someone researching his problem will note the class is
not final and base a design on that. when he actually comes to do the
work of extending the class he finds out when he compiles he is in
trouble since the super constructor is private. He has wasted time
designing and writing his class. That is tantalising. Shoot the
asshole who pulled this childish stunt.

...

When the constructor is declared private, it can be documented. The
developer who does the research will definitely come across the
documentation of the class and realize that it has a private
constructor and thought it is non-final, it cannot be extended. So it
is is common sense that he wud not waste his time developing a subclass
to a class which he knows is not inheritable.
 
R

Ranganath Kini

Besides, nothing stops bad design. The language to its best possible
extent prevents accidental design flaws, but intentional efforts cannot
be stopped. So if developer decides to create a bad design, it's his
call.

In object oriented world, contracts rely on other contracts to do what
they are supposed to do. There has to be a default level of trust among
objects. In an ideal world, developers make their best effort to ensure
that their object implementation does what the object's public contract
declares to do in the manner that it does. But there is nothing to
enforce this kind of nature in the language.
 
E

EJP

Roedy said:
On Thu, 09 Feb 2006 08:36:19 GMT, EJP
I am confused since we have been discussing vaguely related issues in
different threads.

Not me.
1. if you use wildcard imports you can get he wrong class and not
notice even at run time. All that has to happen is the signatures to
match of the methods you actually use.

I agree, but this applies to *any* class, whether a mis-import or an
alternate implementation, which doesn't entirely meet the binary
contract of the expected class.
2. if someone makes all constructors private but leaves the class
itself public, someone researching his problem will note the class is
not final and base a design on that. when he actually comes to do the
work of extending the class he finds out when he compiles he is in
trouble since the super constructor is private. He has wasted time
designing and writing his class. That is tantalising. Shoot the
asshole who pulled this childish stunt.

I disagree. He has wasted his time by not doing his homework. This
applies to many situations, not just this one.

In *the situation under discussion*, there may be legitimate reasons for
making it non-final but with private constructors. The abstract factory
pattern is an example: the concrete subclass can be provided as a static
inner class. This seems like a useful feature to me and I may even have
used it some time.

Your language is not justified.
 
R

Roedy Green

I agree, but this applies to *any* class, whether a mis-import or an
alternate implementation, which doesn't entirely meet the binary
contract of the expected class.

but it won't likely happen because if the class names differ because
you explicitly mention the class name in your code. The confusion
comes with generic wildcards that can give you an alternative class
you did not even know about.
 
R

Roedy Green

I disagree. He has wasted his time by not doing his homework. This
applies to many situations, not just this one.

It is a trap for the unwary. There is no benefit in it. It is
motivated by malicious pranksterism. So I put the blame on the person
who set the trap, not the one who fell into in. Maintainable code
should not have traps.
 
E

EJP

Roedy said:
It is a trap for the unwary. There is no benefit in it. It is
motivated by malicious pranksterism.

1. It is a trap for the unwary. I agree. There are many of these in Java
and elsewhere.

2. The benefit has already been cited, but, to re-iterate, it provides
finer-grained control over *who* may subclass the class. Consider this
form of the abstract factory pattern:

public abstract class AbstractFactory
{
private AbstractFactory() {}
public abstract MyObject createMyObject();
public static createFactory() { return new ConcreteFactory(); }

static class ConcreteFactory extends AbstractFactory
{
public Object createMyObject() { return new MyObject(); }
}
}

You might describe the ability to write that as a marginal or dubious
benefit, but it is certainly not 'no benefit'. Consider also the case
where the constructors in question are protected or package-private.

3. You can ignore evidence all you want, but when you are reduced to
speculating on motives (whose?) you are getting pretty ridiculous.
 
R

Roedy Green

2. The benefit has already been cited, but, to re-iterate, it provides
finer-grained control over *who* may subclass the class. Consider this
form of the abstract factory pattern:

public abstract class AbstractFactory
{
private AbstractFactory() {}
public abstract MyObject createMyObject();
public static createFactory() { return new ConcreteFactory(); }

static class ConcreteFactory extends AbstractFactory
{
public Object createMyObject() { return new MyObject(); }
}
}

I don't understand your benefit. With this convolution what the net
result Who do you include/exclude doing it both ways.

Even if that were true it is too weird and convoluted. Don't do it.
 

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

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top