I have interface:
public interface Doable {
void doSomething();
}
and the class that implements it:
public class DoJump() implements Doable {
#Override
private void doSomething() {
fireJumpHandler();
}
}
This is stupid example, but I would like to present the problem.
This code doesn't compile, I am getting an error in Eclipse IDE:
Cannot reduce the visibility of the inherited method from
Doable
I have common interface that declares a method. This method is overriden in concrete class. I would like to avoid another class that can extend this class (DoJump), so I would like to hide this method from sub classes. I would like to use private modifier, but Java does not allow me to do it.
Why it is impossible, and how to workaround it?
I'd like to answer your last question "How to workaround it?" as this is not described in the related question. Create a second interface NotDoable which simply does not have doSomething() declared. Then let your DoJump implement both interfaces. Give everyone that shouldn't override doSomething a reference to the interface NotDoable instead of the true type DoJump. Then they won't know that the object truly can doSomething, they won't know per class design. Of course, one can workaround this but one actually can workaround everything. The class design is more correct this way. Here's some code:
public interface Doable {
public void doSomething();
}
public interface NotDoable {
}
public class DoJump implements Doable, NotDoable {
#Override
public void doSomething() {
System.out.println("hi");
}
public NotDoable meAsNotDoable() {
return this;
}
public static void main(String[] args) {
DoJump object = new DoJump();
// This call is possible, no errors
object.doSomething();
NotDoable hidden = object.meAsNotDoable();
// Not possible, compile error, the true type is hidden!
hidden.doSomething();
}
}
But as said, one can workaround this by using if (hidden instanceof DoJump) { DoJump trueObject = (DoJump) hidden; }. But well, one can also access private values via reflection.
Other classes now implement NotDoable instead of extending DoJump. If you declare everything others should know about DoJump in this interface, then they only can do what they should do. You may call this interface IDoJump and the implementing class DoJump, a common pattern.
Now the same a bit more concrete.
public interface IDog {
public void bark();
}
public interface ICanFly {
public void fly();
}
public class FlyingDog implements IDog, ICanFly {
#Override
public void bark() {
System.out.println("wuff");
}
#Override
public void fly() {
System.out.println("Whuiiii");
}
public static void main(String[] args) {
FlyingDog flyingDog = new FlyingDog();
// Both works
flyingDog.fly();
flyingDog.bark();
IDog dog = (IDog) flyingDog;
// Same object but does not work, compile error
dog.fly();
ICanFly canFly = (ICanFly) flyingDog;
// Same object but does not work, compile error
canFly.bark();
}
}
And now an extending class.
public class LoudDog implements IDog {
#Override
public void bark() {
System.out.println("WUUUUFF");
}
// Does not work, compile error as IDog does not declare this method
#Override
public void fly() {
System.out.println("I wanna fly :(");
}
}
In the end, be aware that if others know that their IDog actually is a FlyingDog (and they cast it), then they must be able to call fly() as a FlyingDog must can fly. Furthermore, they must be able to override the behavior as long as they follow the specification of fly() given by its method-signature. Imagine a subclass called PoorFlyingDog, he needs to override the default behavior, else he can perfectly fly, but he is a poor flyer.
Summarized: Hide to others that you're actually a DoJump, also hide that you are a Doable, pretend to only be a NotDoable. Or with the animals, pretend to only be an IDog instead of a FlyingDog or ICanFly. If the others don't cheat (casting), they won't be able to use fly() on you, though you actually can fly.
Add final to DoJump declaration to prevent this class to be overriden (and therefore doSomething() to be overriden too).
public final class DoJump implements Doable {
#Override
public void doSomething() {
fireJumpHandler();
}
}
If you still need to be able to inherit DoJump but you don't want doSomething() to be overriden, put the final modifier in the method signature
public class DoJump implements Doable {
#Override
public final void doSomething() {
fireJumpHandler();
}
}
Related
In my project I have a superclass and two subclasses extending from it. There is a method in the superclass that is overriden differently in each subclass.
I want to know if it's possible to introduce a method (in another class) that takes object of either subclass as a parameter and calls a method overriden in one of subclasses (depending on to which subclass does the object belong).
public class Superclass{
public int method(){return 0;}
}
public class Subclass1 extends Superclass{
public int method(){return 1;}
}
public class Subclass2 extends Superclass{
public int method(){return 2;}
}
public class CallingClass{
public static int dependantCall(Superclass parameter){return parameter.method}
I want to be able to do something like
Subclass1 subclassObject = new Subclass1;
System.out.println(CallingClass.dependantCall(subclassObject));
and get output
1
That is what Polymorphism is for! Defining the Superclass as a parameter type will allow you to pass either subclass in.
For example in your other class you can define it like this:
// classes Dog and Cat extend Animal and override makeNoise()
class Owner{
playWith(Animal a){
a.makeNoise();
}
}
Now the Owner can accept owner.makeNoise(cat) and owner.makeNoise(dog)
More reading: https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
Yes, it is entirely possible. Here's how that method would look like:
public <T extends Superclass> void foo(T subclassObject) {
...
}
Or:
public void foo(Superclass obj) {
...
}
Note that in the above method, you can pass subclasses' objects as well (they are covariant data types).
This is what Java does by default when you create subclases, so no need to do anything special. Each object carries it's type information at run time, and the method invoked would always be the most specific one for the object. Example:
public class Doer {
public void doSomething() {
// Body presence
};
}
public class Painter extends Doer {
#Override
public void doSomething() {
// Paint here
}
}
public class Manager extends Doer {
#Override
public void doSomething() {
// Micromanage here
}
}
// Elsewhere in your code:
public void busyness(Doer doer) {
doer.doSomething();
}
A style note: if it is possible, one should prefer using interfaces instead of base classes (base classes those should be used only if you want to share implementation between subclasses). Example with interfaces:
public interface Doer {
void doSomething();
}
public class JackOfAllTrades implements Does {
#Override
public void doSomething() {
// Do whatever necessary
}
}
// Client code stays exactly the same as above:
public void busyness(Doer doer) {
doer.doSomething();
}
Note that in Java a class can have only one base class but can implement multiple interfaces.
#Override annotations are not strictly required, but they help Java compiler to spot some errors for you (e.g. if you misprint method name).
In your example it would look like
public class CallingClass {
public static int dependantCall(Superclass parameter) {
return parameter.method();
}
}
Subclass1 subclassObject = new Subclass1();
System.out.println(CallingClass.dependantCall(subclassObject));
Here's the situation: I have a class and I create instances of. I'd like it to inherit the majority of the methods/variables in the class, but I want a few methods to be required to be overridden, similar to how an abstract class works.
Here is my code so far.
public class Example {
public void methodOne() {
//Inherited
}
public void methodTwo() {
//Interited
//Maybe calls methodThree() as a part of its function
}
public void methodThree() {
//Override Me
}
}
I can't [make the class abstract] because I need to create instances
Making the class abstract does prevent instantiation, but since you want to prevent instantiation unless a method is overridden, this is the right thing to do.
You can make overrides anonymously, so syntactically this would be similar to instantiating the base class:
public abstract class Example {
public void methodOne() {
//Inherited
}
public void methodTwo() {
//Interited
//Maybe calls methodThree() as a part of its function
}
public abstract void methodThree();
}
...
static void main(String[] args) {
Example e = new Example() {
#Override
public void methodThree() {
... // Do something
}
};
}
First of all, requiring people to write code in a particular way can be counter productive. Someone may have a legitimate use-case (that you had not considered !!) for dong it differently, and your restriction may force them to solve the problem in a way that makes things significantly worse than if your restriction wasn't there. Bear this in mind ...
But here's a solution:
public abstract class ExampleBase {
public void methodOne() {
// Inherited
}
public void methodTwo() {
// Interited
// Maybe calls methodThree() as a part of its function
}
public abstract void methodThree();
}
public final class Example {
#Override
public void methodThree() {
// Do stuff.
}
}
We have solved the problem by moving all of the members that you want to inherit to an abstract superclass. Any methods that you want to force people to override are declared as abstract. By declaring your concrete Example class as final, we prevent them from circumventing your requirement and subclassing Example without overriding methodThree.
Which access modifier, in an abstract class, do I have to use for a method,
so the subclasses can decide whether it should be public or not? Is it possible to "override" a modifier in Java or not?
public abstract class A {
??? void method();
}
public class B extends A {
#Override
public void method(){
// TODO
}
}
public class C extends B {
#Override
private void method(){
// TODO
}
}
I know that there will be a problem with static binding, if
someone calls:
// Will work
A foo = new B()
foo.method();
// Compiler ?
A foo = new C();
foo.method();
But maybe there is another way. How I can achieve that?
It is possible to relax the restriction, but not to make it more restrictive:
public abstract class A {
protected void method();
}
public class B extends A {
#Override
public void method(){ // OK
}
}
public class C extends A {
#Override
private void method(){ // not allowed
}
}
Making the original method private won't work either, since such method isn't visible in subclasses and therefore cannot be overriden.
I would recommend using interfaces to selectively expose or hide the method:
public interface WithMethod {
// other methods
void method();
}
public interface WithoutMethod {
// other methods
// no 'method()'
}
public abstract class A {
protected void method();
}
public class B extends A implements WithMethod {
#Override
public void method(){
//TODO
}
}
public class C extends B implements WithoutMethod {
// no 'method()'
}
... then only work with the instances through the interfaces.
When overriding methods, you can only change the modifier to a wider one, not vice versa. For example this code would be valid:
public abstract class A {
protected void method();
}
public class B extends A {
#Override
public void method() { }
}
However, if you try to narrow down the visibility, you'd get a compile-time error:
public abstract class A {
protected void method();
}
public class B extends A {
#Override
private void method() {}
}
For your case, I'd suggest to make C not implementing A, as A's abstraction implies that there's a non-private method():
public class C {
private void method(){
//TODO
}
}
Another option is to make the method() implementation in C throwing a RuntimeException:
public class C extends A {
#Override
public void method(){
throw new UnsupportedOperationException("C doesn't support callbacks to method()");
}
}
What you are asking for is not possible for very good reasons.
The Liskov substitution principle basically says: a class S is a subclass of another class T only then, when you can replace any occurrence of some "T object" with some "S object" - without noticing.
If you would allow that S is reducing a public method to private, then you can't do that any more. Because all of a sudden, that method that could be called while using some T ... isn't available any more to be called on S.
Long story short: inheritance is not something that simply falls out of the sky. It is a property of classes that you as the programmer are responsible for. In other words: inheritance means more than just writing down "class S extends T" in your source code!
This is impossible because of the polymorphism. Consider the following. You have the method in class A with some access modifier which is not private. Why not private? Because if it was private, then no other class could even know of its existence. So it has to be something else, and that something else must be accessible from somewhere.
Now let's suppose that you pass an instance of class C to somewhere. But you upcast it to A beforehand, and so you end up having this code somewhere:
void somewhereMethod(A instance) {
instance.method(); // Ouch! Calling a private method on class C.
}
One nice example how this got broken is QSaveFile in Qt. Unlike Java, C++ actually allows to lower access privileges. So they did just that, forbidding the close() method. What they ended up with is a QIODevice subclass that is not really a QIODevice any more. If you pass a pointer to QSaveFile to some method accepting QIODevice*, they can still call close() because it's public in QIODevice. They “fixed” this by making QSaveFile::close() (which is private) call abort(), so if you do something like that, your program immediately crashes. Not a very nice “solution”, but there is no better one. And it's just an example of bad OO design. That's why Java doesn't allow it.
Edit
Not that I missed that your class is abstract, but I also missed the fact that B extends C, not A. This way what you want to do is completely impossible. If the method is public in B, it will be public in all subclasses too. The only thing you can do is document that it shouldn't be called and maybe override it to throw UnsupportedOperationException. But that would lead to the same problems as with QSaveFile. Remember that users of your class may not even know that it's an instance of C so they won't even have a chance to read its documentation.
Overall it's just a very bad idea OO-wise. Perhaps you should ask another question about the exact problem you're trying to solve with this hierarchy, and maybe you'll get some decent advises on how to do it properly.
Here is a part of the #Override contract.
The answer is : there isn't any possibility to achieve what you have.
The access level cannot be more restrictive than the overridden
method's access level. For example: if the superclass method is
declared public then the overridding method in the sub class cannot be
either private or protected.
This is not a problem concerning abstract classes only but all classes and methods.
THEORY:
You have the determined modifiers order:
public <- protected <- default-access X<- private
When you override the method, you can increase, but not decrease the modifier level. For example,
public -> []
protected -> [public]
default-access -> [public, default-access]
private -> []
PRACTICE:
In your case, you cannot turn ??? into some modifier, because private is the lowest modifier and private class members are not inherited.
I would like to prevent a class from calling its own method. The method shall only be callable by its super class.
Right now, I cannot think of any way to achieve this (cleanly). But maybe someone knows a solution?
In code:
public abstract class A {
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
public class B extends A {
#Override
protected void foo() {
//do smth
}
private void barB() {
//must not be able to call foo() here
}
}
Edit: the explanation why I would like to do this:
A is lets say a vehicle. B can be a car or an airplane. The method foo() would be startEngines(). -> I want to make sure that the engines can only be started by calling the method barA().... does that make any sense?
There is a way to do it, but you need to use Google Error Prone. This is an extension of the Java compiler that aims to provide more and more helpful warnings and errors (similar to FindBugs and PMD, but with less false alarms). I can only recommend it, it has already helped us to find some bugs.
Specifically, it contains an annotation #ForOverride and an according compile-time check. This annotation is meant to be used for protected methods that the sub-class and any other class should not call, but only the defining class.
So using
public abstract class A {
#ForOverride
protected abstract void foo();
private void barA() {
//do smth
foo();
}
}
would exactly achieve what you want.
You can integrate Error Prone into most build systems like Maven and Ant. Of course, it won't help if somebody compiles your source without Error Prone (for example in Eclipse), but using it in a continous-integration system would still allow you to find such issues. The source code still stays compatible with regular Java compilers (provided you have error_prone_annotations.jar on the class path), other compilers will simply not do the additional checks.
this answer has a good hint.
add below method in your class (class B):
public static String getMethodName(final int depth)
{
final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
return ste[ste.length - 1 - depth].getMethodName();
}
and change the foo method in class B to this:
#Override
protected void foo() {
//....
if (getMethodName(0)=="barB"){
// tell you are not able to call barB
}
}
Considering your vehicle and engine scenario, I think you need to reconsider your design a bit.
Your vehicle could be a car, aeroplane, etc but car, aeroplane, ... each have separate engines and therefore different startEngine method. So declare your class vehicle as abstract like you did and class startEngine as abstract method . Next , subclass Vehicle and implement startEngine in them , now you can invoke startEngine on the subclass instances
abstract class Vehicle{
abstract void startEngine();
}
public class Car extends Vehicle{
public void startEngine(){
//implementation
}
public static void main(String[] arg){
Vehicle v=new Car();
v.startEngine();
}
}
Add Anonymouse inner class to barA method via Interface, so you will need to implement a method for foo() (functional interface). It won't be part of Class B.
you could put an interface as a member in the super class given to it via the constructor. the child class implements the method but can't call it except by making it static.
interface Foo {
void stopEngines();
void startEngines();
}
abstract class Base {
final private Foo foo;
public Base(final Foo foo) {
this.foo = foo;
}
private void barA() {
// do smth
foo.startEngines();
}
}
class Child extends Base {
public Child() {
super(new Foo() {
boolean engineRunning;
#Override
public void stopEngines() {
this.engineRunning = false;
}
#Override
public void startEngines() {
this.engineRunning = true;
}
});
}
private void barB() {
// can't call startEngines() or stopEngines() here
}
}
class Child2 extends Base {
public Child2() {
super(new Foo() {
#Override
public void stopEngines() {
stopEngines();
}
#Override
public void startEngines() {
startEngines();
}
});
}
static void stopEngines() {
// influence some static state?
}
static void startEngines() {
// influence some static state?
}
private void barB() {
// can call stopEngines() and startEngines(), but at least they have to be static
}
}
Of course, this is not really what you asked for, but about as much as you can do about it in Java, I guess.
Seeing the startEngines explanation, this solution might even suffice.
I guess you wouldn't care about the class calling its static methods, since they can only influence a static state, which is used seldom. The methods within the anonymous interface implementation can mutually call each other, but I guess that would be OK, since you only seem to be trying to prevent others to start the engines in some different way.
I guess this is similar to the problem AWT/Swing has with overriding the paint(Graphics g) method on a component (or onCreate(..) in Android Activities). Here you are overriding the paint method but you should never call it.
I think the best thing you can do is add documentation to the method to clarify that it should never be explicitly called by the subclasses OR re-evaluate your design.
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
System.out.println("Dont go here please");
}
public void thisMethod(SpecificFoo specificFoo) {
// not into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}
calling code:
SomeClass myClass = new SomeClass();
SomeOlderClass olderClass = new SomeOlderClass(myClass);
I have an interface (SomeInterface) that several classes call into (such as SomeOlderClass). I have a class that implements the interface, but I want to do type safe operations on the specific implementations that are passed into the generic interface.
As shown in the above code, I really want to able to make another method that matches the specific type passed in to the interface. This doesn't work. I assume it is because the calling code only knows about the interface, and not the implementation with the more specific methods (even though SpecificFoo implements Foo)
So how can I do this in the most elegant way? I can get the code working by adding an if statement in the class implementing the interface (SomeClass):
public void thisMethod(Foo someKindOfFoo) {
// calling code goes into this function
if ( someKindOfFoo.getClass().equals(SpecificFoo.class) )
thisMethod(SpecificFoo.class.cast(someKindOfFoo));
else
System.out.println("Dont go here please");
}
However, this is not elegant, as I have to add if statements everytime I add a new kind of Foo. And I might forget to do so.
The other option is to add SpecificFoo to the SomeInterface, and let the compiler sort out reminding me that I need implementations in SomeClass. The problem with this is that I end up adding quite a bit of boiler plate code. (If someone else implements the interface, they have to implement the new method, as well as any tests)
It seems that there should be another option I am missing, given that Foo and SpecificFoo are related. Ideas?
MORE INFO:
Well I actually worked for a while to try and simplify the question. As I add more details the complexity goes up by quite a bit. But whatever... I think I can explain it.
Basically, I am write a GWT web apps RPC servlet using the command pattern as explained by Ray Ryan in his talk
There are several implementations of it on google code, but many of them suffer this inherit problem. I thought it was a bug in the GWT-RPC code bugreport HOWEVER, as I was implementing further I noticed a similar problem happening purely on the client side, and while in hosted mode. (ie all java, no gwt javascript madness).
So I abstracted the basic ideas to a raw java command line case, and saw the same issue, as described above.
If you follow along with what Ray Ryan discusses, Foo is an Action, SpecificFoo is a specific action I want to call. SomeInterface is the client side RPC service and SomeClass is the server side RPC class. SomeOlderClass is a kind of rpc service that would know about cacheing and whatnot.
Obvious, right? Well as I said, I think all the GWT RPC nonsense just muddies up the waters on the base issue, which is why I tried to simplify it as best I could.
If you need to find out the actual type of an object at runtime, then the design is most probably wrong. That violates at least the Open Closed Principle and Dependency Inversion Principle.
(Because Java does not have multiple dispatch, the thisMethod(Foo)will be called instead of thisMethod(SpecificFoo). Double dispatch could be used to get around the language's limitations, but there might still be some design problem lurking there...)
Please give more information on what you are trying to accomplish. Right now the question does not provide enough information to come up with a right design.
A generic solution is that since the action depends on the runtime type of Foo, that method should be part of Foo so that its implementation can vary depending on Foo's type. So your example would be changed to something like below (possibly adding SomeInterface or other parameters to thisMethod()).
public interface Foo {
void thisMethod();
}
public class SpecificFoo implements Foo {
public void thisMethod() {
System.out.println("Go here please");
}
}
Try using double dispatch: Add a method to the Foo interface that is called by SomeClass#thisMethod. Then place the code in the implementation of this method.
public interface Foo {
public void thatMethod(SomeClass a);
public void thatMethod(SomeOlderClass a);
}
public class SomeClass implements SomeInterface {
public void thisMethod(Foo someKindOfFoo) {
someKindOfFoo.thatMethod(this);
}
}
Sorry, I find the problem description far too abstract to be able to make a recommendation. You clearly have a design issue because you generally should not need to check the type of interface. I will give it a go though... First, I need to make your problem more concrete for my small brain to understand. Instead of Foos, how about Birds?
public interface Bird {
}
public class Ostrich implements Bird {
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
System.out.println("I am in the air. Yay!");
}
public void fly(Ostrich ostrich) {
System.out.println("Sigh... I can't fly.");
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Here, the Ostrich will declare "I am in the air. Yay!" which is not what we want.
OK, so, ignoring the fact that I am failing basic OO here, the problem is that the BirdManager will look for the least-specific method that matches the type that is passed in. So no matter what kind of bird I give it, it will always match fly(Bird). We can put some if checks in there, but as you add more types of birds, your design will degrade further. Here's the tough part - I have no idea if this makes sense within the context of your problem, but consider this refactoring where I move the logic from the manager into bird:
public interface Bird {
void fly();
}
public class BasicBird implements Bird {
public void fly() {
System.out.println("I am in the air. Yay!");
}
}
public class Ostrich implements Bird {
public void fly() {
System.out.println("Sigh... I can't fly.");
}
}
public interface BirdManager {
void fly(Bird bird);
}
public class AdvancedBirdManager implements BirdManager {
public void fly(Bird bird) {
bird.fly();
}
}
public class ZooSimulation {
public ZooSimulation(BirdManager birdManager) {
Ostrich ostrich = new Ostrich();
birdManager.fly(ostrich);
}
}
public static void main(String[] args) {
AdvancedBirdManager advancedBirdManager = new AdvancedBirdManager();
ZooSimulation zooSimulation = new ZooSimulation(advancedBirdManager);
}
Our Ostrich now says the correct thing and the bird manager still treats it as just a bird. Again, bad OO (Ostriches should not have fly() methods) but it illustrates my thoughts.
As long as there are not too many implementations of Foo, I would declare an abstract method in SomeInterface for each subclass of Foo, and have an abstract class forward calls to a default method that is defined for the most general type:
public interface Foo {
}
public class SpecificFoo implements Foo {
}
public interface SomeInterface {
void thisMethod(Foo someKindOfFoo);
void thisMethod(SpecificFoo specificFoo);
void thisMethod(OtherSpecificFoo otherSpecificFoo);
}
public abstract class AbstractSomeInterface {
public void thisMethod(Foo wrongFoo) {
throw new IllegalArgumentException("Wrong kind of Foo!");
}
public void thisMethod(SpecificFoo specificFoo) {
this.thisMethod((Foo) specificFoo);
}
public void thisMethod(OtherSpecificFoo otherSpecificFoo) {
this.thisMethod((Foo) specificFoo);
}
}
public class SomeClass extends AbstractSomeInterface {
public void thisMethod(SpecificFoo specificFoo) {
// calling code goes into this function
System.out.println("Go here please");
}
}
public class SomeOlderClass {
public SomeOlderClass( SomeInterface inInterface ) {
SpecificFoo myFoo = new SpecificFoo();
inInterface.thisMethod(myFoo);
}
}