Java, hiding methods of super super class - java

I am porting some OpenGL Nvidia C samples to jogl and I have the following (init is one of the abstract methods required by GLEventListener:
public abstract class NvAppBase implements GLEventListener {
#Override
public void init(GLAutoDrawable drawable) {
initRendering(gl4);
}
public void initRendering(GL4 gl4) {
}
}
public abstract class NvSampleApp extends NvAppBase {
#Override
public void init(GLAutoDrawable drawable) {
baseInitRendering(gl4);
}
protected void baseInitRendering(GL4 gl4) {
initRendering(gl4);
}
#Override
public void initRendering(GL4 gl4) {
}
}
public class BindlessApp extends NvSampleApp{
#Override
public void initRendering(GL4 gl4) {
}
}
Given that:
NvAppBase is not used at all, all the samples (such as BindlessApp) always extend NvSampleApp
I'd like the class extending NvSampleApp to being able to see (and overwrite) only the initRendering and not also the init
Is there a better way than just having NvSampleApp simply as a variable inside BindlessApp, like this for example?
public class BindlessApp {
private NvSampleApp sampleApp;
}

You can use the keyword final for this purpose.
Writing Final Classes and Methods on Oracle java tutorial.
You can declare some or all of a class's methods final. You use the
final keyword in a method declaration to indicate that the method
cannot be overridden by subclasses. The Object class does this—a
number of its methods are final.

Is there a better way than just having NvSampleApp simply as a
variable inside BindlessApp, like this for example?
Although it seems like more work, encapsulation is a great tool to help isolate parts of your code an decrease coupling.
I think in your case it might even be the better solution :)
See for more detail this answer: https://stackoverflow.com/a/18301036/461499

Related

How to protect a method implementing an interface from overriding?

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();
}
}

Require Instance of Class to Override a Method

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.

Can an overriding method have a different access specifier from that in the base class?

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.

Java: method only callable by superclass

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.

Avoiding multiple implementations of the same method in different context

I have a simple design question. I am not sure how to design the following "situation" with respect to scalability and object-orientation.
interface IA {
void update();
}
class A implements IA {
public void update(){
updateInX();
updateInY();
}
private void updateInX(){
...
}
private void updateInX(){
...
}
}
The redundancy (updateInX(), updateInY()) seems like a bad design, but I have no idea how to improve it. I would appreciate your help!
This problem can be solved using Template method design pattern. You will basically define abstract class which contains abstract methods which has to be overriden and leave the computation itself on the abstract class. For instance
public abstract class Something {
public void update(){
updateInX();
updateInY();
printResult();
}
private void printResult() {
//print
}
protected abstract void updateInX();
protected abstract void updateInX();
}
This will make a child object implement only necessary methods and leave the computation on the base class.

Categories

Resources