Related
While refactoring I came across the following method in a subclass:
public void disposeResultsTable() {
super.disposeResultsTable();
}
What are the benefits to keeping this method rather than simply allowing the inherited superclass method to be called?
The only technical reason I can think of is what Michael proposed in the comments - making a restricted method become public.
However, I can think of a few human reasons.
For instance, this could be a convenient place to place a breakpoint for debugging invocations of disposeResultsTable of the child class. Or perhaps this was meant as a placeholder - "remember to implement this method for this class", or maybe someone wanted to explicitly point out to the reader of this code that this class uses the parent's implementation of disposeResultsTable. There are probably a bunch more options.
Have you tried looking up the history of this piece of code in the VCS? Maybe there's a helpful commit message from the original author.
The answer by Malt shows a common reason for overriding a method trivially by only calling the super implementation, namely to change the visibility from protected to public. Whether or not this might be the case in your example depends on the visibility of the respective method in the superclass...
However, there is another possible reason - although it might be a bit far-fetched and unusual - and this possible reason is reflection: The Class#getDeclaredMethods method only returns the methods that are... well, declared in this class.
For example, consider the following program:
import java.lang.reflect.Method;
public class TrivialOverride
{
static class BaseClass
{
void method0() {}
void method1() {}
}
static class ChildClass extends BaseClass
{
void method0() {}
}
public static void main(String[] args)
{
printDeclaredMethods(BaseClass.class);
printDeclaredMethods(ChildClass.class);
}
private static void printDeclaredMethods(Class<?> c)
{
System.out.println("Declared methods in " + c.getSimpleName());
for (Method m : c.getDeclaredMethods())
{
System.out.println(m.getName());
}
System.out.println();
}
}
The output is
Declared methods in BaseClass
method0
method1
Declared methods in ChildClass
method0
So method0 only appears in the list of declared methods of the child class because it was overridden from the base class.
I know that an interface must be public. However, I don't want that.
I want my implemented methods to only be accessible from their own package, so I want my implemented methods to be protected.
The problem is I can't make the interface or the implemented methods protected.
What is a work around? Is there a design pattern that pertains to this problem?
From the Java guide, an abstract class wouldn't do the job either.
read this.
"The public access specifier indicates that the interface can be used by any class in any package. If you do not specify that the interface is public, your interface will be accessible only to classes defined in the same package as the interface."
Is that what you want?
You class can use package protection and still implement an interface:
class Foo implements Runnable
{
public void run()
{
}
}
If you want some methods to be protected / package and others not, it sounds like your classes have more than one responsibility, and should be split into multiple.
Edit after reading comments to this and other responses:
If your are somehow thinking that the visibility of a method affects the ability to invoke that method, think again. Without going to extremes, you cannot prevent someone from using reflection to identify your class' methods and invoke them. However, this is a non-issue: unless someone is trying to crack your code, they're not going to invoke random methods.
Instead, think of private / protected methods as defining a contract for subclasses, and use interfaces to define the contract with the outside world.
Oh, and to the person who decided my example should use K&R bracing: if it's specified in the Terms of Service, sure. Otherwise, can't you find anything better to do with your time?
When I have butted up against this I use a package accessible inner or nested class to implement the interface, pushing the implemented method out of the public class.
Usually it's because I have a class with a specific public API which must implement something else to get it's job done (quite often because the something else was a callback disguised as an interface <grin>) - this happens a lot with things like Comparable. I don't want the public API polluted with the (forced public) interface implementation.
Hope this helps.
Also, if you truly want the methods accessed only by the package, you don't want the protected scope specifier, you want the default (omitted) scope specifier. Using protected will, of course, allow subclasses to see the methods.
BTW, I think that the reason interface methods are inferred to be public is because it is very much the exception to have an interface which is only implemented by classes in the same package; they are very much most often invoked by something in another package, which means they need to be public.
This question is based on a wrong statement:
I know that an interface must be public
Not really, you can have interfaces with default access modifier.
The problem is I can't make the interface or the implemented methods protected
Here it is:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
Hence, achieving what you wanted, prevent interface and class usage outside of the package.
Here's how it could be done using abstract classes.
The only inconvenient is that it makes you "subclass".
As per the java guide, you should follow that advice "most" of the times, but I think in this situation it will be ok.
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
Here's another solution, inspired by the C++ Pimpl idiom.
If you want to implement an interface, but don't want that implementation to be public, you can create a composed object of an anonymous inner class that implements the interface.
Here's an example. Let's say you have this interface:
public interface Iface {
public void doSomething();
}
You create an object of the Iface type, and put your implementation in there:
public class IfaceUser {
private int someValue;
// Here's our implementor
private Iface impl = new Iface() {
public void doSomething() {
someValue++;
}
};
}
Whenever you need to invoke doSomething(), you invoke it on your composed impl object.
I just came across this trying to build a protected method with the intention of it only being used in a test case. I wanted to delete test data that I had stuffed into a DB table. In any case I was inspired by #Karl Giesing's post. Unfortunately it did not work. I did figure a way to make it work using a protected inner class.
The interface:
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
Then the inner class defined as protected in public class:
package foo;
public class MyFoo implements SomePublicFoo {
// public stuff
protected class ProtectedFoo implements SomeProtectedFoo {
public int doSomeFoo() { ... }
}
protected ProtectedFoo pFoo;
protected ProtectedFoo gimmeFoo() {
return new ProtectedFoo();
}
}
You can then access the protected method only from other classes in the same package, as my test code was as show:
package foo;
public class FooTest {
MyFoo myFoo = new MyFoo();
void doProtectedFoo() {
myFoo.pFoo = myFoo.gimmeFoo();
myFoo.pFoo.doSomeFoo();
}
}
A little late for the original poster, but hey, I just found it. :D
You can go with encapsulation instead of inheritance.
That is, create your class (which won't inherit anything) and in it, have an instance of the object you want to extend.
Then you can expose only what you want.
The obvious disadvantage of this is that you must explicitly pass-through methods for everything you want exposed. And it won't be a subclass...
I would just create an abstract class. There is no harm in it.
With an interface you want to define methods that can be exposed by a variety of implementing classes.
Having an interface with protected methods just wouldn't serve that purpose.
I am guessing your problem can be solved by redesigning your class hierarchy.
One way to get around this is (depending on the situation) to just make an anonymous inner class that implements the interface that has protected or private scope. For example:
public class Foo {
interface Callback {
void hiddenMethod();
}
public Foo(Callback callback) {
}
}
Then in the user of Foo:
public class Bar {
private Foo.Callback callback = new Foo.Callback() {
#Override public void hiddenMethod() { ... }
};
private Foo foo = new Foo(callback);
}
This saves you from having the following:
public class Bar implements Foo.Callback {
private Foo foo = new Foo(this);
// uh-oh! the method is public!
#Override public void hiddenMethod() { ... }
}
I think u can use it now with Java 9 release. From the openJdk notes for Java 9,
Support for private methods in interfaces was briefly in consideration
for inclusion in Java SE 8 as part of the effort to add support for
Lambda Expressions, but was withdrawn to enable better focus on higher
priority tasks for Java SE 8. It is now proposed that support for
private interface methods be undertaken thereby enabling non abstract
methods of an interface to share code between them.
refer https://bugs.openjdk.java.net/browse/JDK-8071453
I have the following classes.
public class Super{
public static void useSubClass(){
//I want to access the sub class object here, how.
}
}
public class Sub1 extends Super{
}
public class Sub2 extends Super{
}
I want to access the sub-class object from a static method in super-class. i.e. When I call Sub1.useSubClass() the method has access to Sub1.class and when I use Sub2.useSubClass(), I can access the Sub2.class.
Is there any way to access the sub-class object from super-class.
In general, you cannot do that from a superclass (and shouldn't!) because you won't know (and shouldn't assume anything about!) what classes will inherit from your superclass.
Depending on exactly what you want to do, there are alternatives, such as:
Use the template pattern to define "filler methods" that your subclasses must implement; these filler methods will be called by the template method in your superclass.
Define methods to be overridden by your subclass.
Define interfaces to be implemented by your subclass.
Update: As #JB Nizet has pointed out, I might have misread the question.
Here's something (very similar to the Observer Pattern) you can do if you wish to access subclasses from the static method in your superclass:
Define a static listener list in your superclass, call it List observerList
In the constructor of your superclass, add the class instance itself to that static observerList
For all subclasses, it is their responsibility to call super() from their constructors in order to register themselves to observerList (and unregister in deconstructor)
Then in your superclass's static useSubClass() method, you can iterate through that list of subclass instances, find the particular one you care about (maybe specified by some argument), and then do something with it.
Static methods are not inherited, and calling Sub2.useSubClass() is strictly equivalent to calling Super.useSubclass().
There is no way to get this information, because it doesn't exist. The compiler allows calling Sub2.useSubclass(), but translates it into Super.useSubclass().
public static void useSubClass(Super sub) {
if (sub instanceof Sub1) {
// Do something
} else if (sub instanceof Sub2) {
// Do something else
} else {
// Something else is extending Super
}
}
However, a better question is why? Can't you simply override the method in your subclass?
No you cannot because the super-class cannot know the methods of the sub-classes.
You should consider to create a new class which sees both super-class and sub-classes and implement the static method inside this new class
For the record, you could do this in Python, using class methods:
class super(object):
#classmethod
def usesubclass(cls):
print cls
class sub1(super):
pass
class sub2(super):
pass
Using this code, you could call sub1.usesubclass() or sub2.usesubclass(), and that would print the representations of the sub1 and sub2 classes, respectively:
>>> sub1.usesubclass()
<class '__main__.sub1'>
>>> sub2.usesubclass()
<class '__main__.sub2'>
Java, however, does not support such mechanisms, unfortunately. When you compile Sub1.useSubClass() in your example, the compiler will simply use Sub1 as the basic namespace to look up the the useSubClass() method in Super, but no information on that is actually compiled into code. In the resulting bytecode, the call is simply one directly to Super.useSubClass() and nothing more.
I sympathize with your plight, but Java is what it is. The closest thing you could come, I think, would be the following code:
public class Super {
public static <T extends Super> void useSubClass(Class<T> sub) {
}
}
And then call that method explicitly as either Super.useSubClass(Sub1.class) or Super.useSubClass(Sub2.class).
I figured something out. It works if implemented with care.
/** SuperClass.java **/
public abstract class SuperClass {
public static void printClass(){
System.out.println(new ImplementingClassRetriever().getCallingClass());
}
static class ImplementingClassRetriever extends SecurityManager{
public Class getCallingClass() {
Class[] classes = getClassContext();
for (Class clazz : classes) {
if (SuperClass.class.isAssignableFrom(clazz) && clazz != null
&& !clazz.equals(SuperClass.class)) {
return clazz;
}
}
return null;
}
}
}
/** Main.java **/
public class Main{
public static void main(String[] args) {
Sub.printClass(); //this does not work
Sub.testStaticCall(); //this works!! :)
}
}
class Sub extends SuperClass{
public static void testStaticCall(){
Sub.printClass(); //calling the method in the super class
}
}
This is just a toy example. The super class contains a static class that contains a method to retrieve the calling class.
In the subclass I have another static method which calls the superclass's method for printing the class name.
The Main class/function contains two calls to Sub's inherited and locally implemented method. The first call prints null, because the calling context (i.e. Main) is not a subclass of Super However the delegate method in Sub works because the calling context is now a subclass of SuperClass and hence the calling class can be determined.
Although You can create a reference to the super class and point it to any sub-class. This can also be done dynamically during run-time. This is a way of run-time polymorphism.
I understand what an abstract class is in OOP paradigm. Yeah an abstract class is an incomplete type, cannot be instantiated.
Subclasses of the abstract class can extend the superclass and so on, and call a method through using a base type variable. But that is what I don't get.
I was reading the book, and the author said using a Superclass variable to reference a subclass and calling a common method calls the correct method. And yeah that's true. For example this little code I wrote:
public class ObjectOne extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends SuperObject {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public class SuperObject {
public String objectString()
{
return "SuperObject" ;
}
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem:arr)
{
out.println(elem.objectString()) ;
}
}
}
Em, so when main executes the correct methods are called for the objects using just the reference type. My question is so what is the point of an abstract class? Polymorphism works regardless of whether the method or class is abstract.
Unlike C++, polymorphism works only when you specify it. For Java, it works apparently all the time.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice? Can someone clarify thanks.
I'm not sure you understand what an abstract class is, as none of the classes in your example are abstract, and nothing in there is an interface either. What you are doing is extending an instantiable class. Without the abstract keyword there is nothing to stop me doing:
SuperObject obj = new SuperObject();
I think a better example would be to illustrate how abstract classes are used. What they are commonly used to do is to provide a common method implementation. If a number of classes implement some interface, but all of them implement the same method in the same way using the same code, then what is commonly done is to create an abstract class that contains the common implementation, and get all of the concrete implementations to extend that class. This facilitates code reuse, and decreases the likelihood that one developer will change the common method implementation for one class, but forget the others. For example..
public class ObjectOne extends Thing {
public String objectString()
{
return "objectString() of class ObjectOne\n" ;
}
}
public class ObjectTwo extends Thing {
public String objectString()
{
return "objectString() of class ObjectTwo\n" ;
}
}
public class ObjectThree extends Thing {
public String objectString()
{
return "objectString() of class ObjectThree\n" ;
}
}
public abstract class Thing implements SuperObject {
public String alwaysTheSame() {
return "The same thing";
}
}
public interface SuperObject {
public String objectString();
public String alwaysTheSame();
}
import static java.lang.System.out ;
public class ControlClass {
public static void main(String[] args)
{
SuperObject [] arr = {new ObjectOne(), new ObjectTwo(), new ObjectThree()} ;
for(SuperObject elem : arr)
{
out.println(elem.alwaysTheSame());
out.println(elem.objectString()) ;
}
}
}
What we have done here is introduce an abstract class Thing, which provides a method implementation that is common to all 3 implementations of SuperObject (which is now an interface). This means we don't have to write the same code again in three different places in order to to fully implement the SuperObject interface in each one of our concrete classes.
In addition to this, you can also extend non final classes. You may wish to do this in order to override the default behaviour of one or methods on the concrete class, or to decorate the the class with additional methods. Of course, when you are designing a class hierarchy from scratch you don't stick concrete classes in it that then get extended by other classes, as it's generally considered a bad code smell. However, few of us work with totally new written-from-scratch codebases, and must adapt an exiting codebase to new requirements. Extending a concrete class is one tool in the toolbox to do this.
EDIT: Misunderstood what the OP was asking, but the last paragraph above is relevant.
Let's say you want to deploy an application on an Ipad, Android, Iphone and Desktop application.
You work on an important part that will do 95% of the job in an abstract class. Then you create 4 other small classes that will implement the abstract method differently for each device.
That way, you won't repeat 95% of the work, and each device will instanciate his own class, that extends the abstract common class.
Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.
Here's a good detailed explanation: (extracted from here)
Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.
Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.
You also don't have to implement certain methods in abstract classes. You can decide what have to be declared in Subclasses and what you want declare in the Superclass.
Look at OutputStream for example:
public abstract void write(int i) throws IOException;
public void write(byte abyte0[]) throws IOException {
write(abyte0, 0, abyte0.length);
}
public void write(byte abyte0[], int i, int j) throws IOException {
if(abyte0 == null)
throw new NullPointerException();
if(i < 0 || i > abyte0.length || j < 0 || i + j > abyte0.length || i + j < 0)
throw new IndexOutOfBoundsException();
if(j == 0)
return;
for(int k = 0; k < j; k++)
write(abyte0[i + k]);
}
You have an abstract write method (because you don't knwo where the OutputStream is going to) but all other extra write methods are not abstract and forwarded to this methods. So you only have to declare one method in the Subclass and have some methods "extra" without having to implement it in every Subclass.
You may want a class not to have any instances.
For example assume you have a Person class and two classes derived from it Student and Teacher. In this case you may not want to have any objects created from Person class as it may not have any meaning for your program.
The "point" is to enforce a class hierarchy, potentially with some functionality provided by base class(es), and force some behavior to be implemented by sub-classes.
You would use an abstract class in cases where you do want to specify certain behaviour but don't want anybody to instatiate it directly but having to subclass it.
An abstract class can be full bodied or the skeleton for the subclass. You define your template in the abstract class and its left for the subclass to extend and implement the methods defined in the superclass.
So I guess the abstract keyword or abstract concept is just to complete the inheritance hierarchy, make incomplete types impossible to instantiate, or is to promote good OOP practice?
My answer is yes to everything that you said.
Along with what others have said, you may be using a library written by someone else, where you don't have access to the source code, but want to change it's behavior.
Is there any way to forbid the son class to call the public method of super class in java?
For example
public abstract class TObject{
abstract public void quark();
}
public class Animal extends TObject{
public void quark(){
System.out.println("this is the animal");
}
}
public class Dog extends Animal{
#overide
public void quark(){
System.out.println("this is the animal");
**super.quark();**
}
}
In this example, The Dog call the **super.quark();** in it's quark method.
But I don't want the Dog could call super.quark(); and I also don't want to change the
modifier of quark method in Animal to private. Is there any way to prevent this in compile?
I have be confused couple of days, who can help me........
The reason I do that is I met the similar problem in developing hudson scm plugin.I
created the class which extends the SubversionSCM(the offical class). I just wanted to
override the public method of super class, then call super's public method back like
example. but the compile gave error.I don't konw why, how could it do? Dose java have
something like reflect ways to prevent this?
No, by definition of public you can't stop the method from being called (whether from a derived class or anywhere else). You can of course stop it from being overridden (and thereby ensure that the syntax used to call it won't use super;-) by making it final.
No, there's no way to have a public method that subclasses can't call. The best you can do is document this recommendation.
As a note, it's called a subclass or child class.
The other 2 answers (Alex & Matthew) are basically right.
you can prevent the subclass from calling a public method from the super class
there is probably something wrong with your design if you do this.
The below Father class has two public methods named fatherMethod. Subclasses can call the fatherMethod using reflection (Thank You Matthew for pointing that out.) Without using reflection, subclasses can probably not call either fatherMethod method. Thus it is very similar to a private method.
class Father
{
private class Alpha { }
private class Beta { }
public void fatherMethod ( Alpha param )
{
}
public void fatherMethod ( Beta param )
{
}
}