I'm new to Java and I'm having problems with some OOP, mostly inheritance, concepts.
Consider these two classes:
public class Foo() {
protected String rawData;
public String getSomething(String rawData) {
// ...
this.rawData = rawData;
prepareData();
return rawData;
}
protected void prepareData() {
// do something with class rawData
}
}
public class Bar() extends Foo {
#Override
public String getSomething(String rawData) {
// ...
return super.rawData;
}
#Override
protected void prepareData() {
// do something with class rawData too
}
}
Calling Bar class getSomething() method will lead me to a call of Foo class prepareData()?
Only if your override calls the base method.
Other than base class constructors, Java does not silently call methods for you.
Java always goes deeper even without #Override.
If you don't override the base method it will run it.
If you are in Bar and you want to run Foo method, you can use super.prepareData() in Bar - It will be use when you want to run the super method and add something to it.
Related
I have an abstract class Task with two methods execute() and finish() as the following:
abstract class Task {
abstract void execute();
private void finish() {
// Do something...
}
}
How can I ensure that the overloaded method execute() in subclasses of Task implicitly calls finish() as the last statement?
I don't believe there is any way of 'forcing' sub-classes to invoke a method but you could try some sort of template method approach:
abstract class Foo {
protected abstract void bar(); // <--- Note protected so only visible to this and sub-classes
private void qux() {
// Do something...
}
// This is the `public` template API, you might want this to be final
public final void method() {
bar();
qux();
}
}
The public method is the entry-point and invokes the abstract bar and then the private qux method, this means that any sub-classes follow the template pattern. However it's no panacea of course - a sub-class could simply ignore the public method.
You can create a ExecutorCloseable class that implements the [AutoCloseable] interface, such as:
public class ExecutorCloseable extends Foo implements AutoCloseable
{
#Override
public void execute()
{
// ...
}
#Override //this one comes from AutoCloseable
public void close() //<--will be called after execute is finished
{
super.finish();
}
}
You could call it this way (silly main() example):
public static void main(String[] args)
{
try (ExecutorCloseable ec = new ExecutorCloseable ())
{
ec.execute();
} catch(Exception e){
//...
} finally {
//...
}
}
Hope it makes sense, I can't really know how you call these methods nor how you create the classes. But hey, it's a try : )
For this to work, the finish() method on Foo should be protected or public (first one recommended), though.
I want a method in a derived class to override a virtual method in a CONCRETE base class AND return something (i.e. not void) like this:
public class HelloWorldApp
{
public static void main(String args[])
{
Bar bar = new Bar();
bar.go();
}
}
public class Foo
{
public void go()
{
System.out.print(this.test().toString());
}
protected Integer test()
{
return 1;
}
}
public class Bar extends Foo
{
#Override
protected Integer test()
{
return 2;
}
}
Is there any way of doing this without the redundant 'return 1;' in Foo.test() which will never get run. It works fine obviously but it just seems like I'm doing something badly wrong.
This answer was created before the question was updated to state that the base class must be concrete.
If you expect Foo's test method never to be run, then enforce it by making the Foo class abstract, with test being abstract.
public abstract class Foo {
public void go() {
System.out.print(this.test().toString());
}
abstract protected Integer test();
}
If you cannot make Foo.test() abstract for some reason you didn't show in your example (for example because Foo extends a concrete class) and you are sure it will never be called, throwing a runtime exception may be preferable if there is no reasonable default value:
protected Integer test()
{
throw new UnsupportedOperationException("Calling test on Foo is not supported");
}
There are examples for this in the Java core APIs, see for example UnsupportedOperationException - this one has a slightly different meaning though, it is used for optional methods that some implementations of certain collection-types implement and some don't.
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.
I'm developing a java application using a certain library(included using a jar file), i want to override a method exists on a class(abstract class) contained in that library, or even change a certain parameter value in it.
Is there is a way to do that?
Extend the class from which you want to override the method.
public class ClassFromExtLib {
public void foo(Object param) {
}
}
public class MyClass extends ClassFromExtLib {
#Override
public void foo(Object param) {
super.foo(param);
//adding my own implementation...
}
}
If you can't extend the class, use a wrapper class that can execute the method and then add your own logic to it.
public final class ClassFromExtLib {
public void foo(Object param) {
}
}
public class MyClass {
//code to initialize the instance of the class ommited
private ClassFromExtLib bar;
public void foo(Object param) {
bar.foo(param);
//adding my own implementation...
}
public void foo(Object param, Object param2) {
bar.foo(param);
//adding my own implementation using param and param2...
}
}
If you want to add/remove parameters from the method, then you can't do this by an overriding, that's an overloading. The second way would be the best for you.
Yes and no. You can create a subclass which has the different behavior you want.
public class MyVersion extends JarVersion {
However if you change the signature, callers will typically ignore the change.
You can also use the delegate pattern.
public MyClass {
JarClass delegate;
public void myMethod(MyParm mp) {
JarParm jp = makeJPfromMP(mp);
extraStuff();
delegate.originalMethod(jp);
moreExtraStuff();
}
Its very simple,
Just create one another class that extends that class(assuming its extendable) for which you need modification
And then override the methods that you want to change.
I have a java program which uses arraylists - these arraylists store 'variables' where 'variables' is an abstract class.
Now, to save memory, I want to use a java library called HugeCollections-VanillaJava- however this library requires an interface to be defined.
How do I convert the abstract class into an interface? What rules/restrictions do I have to follow, to correctly perform the conversion?
Finally, is it possible for me to use my abstract class with minimal code changes, so that the library that requires an interface, also works correctly? Ideally I would like not to change the abstract class at all...Is this possible?
how do I convert an abstract class into an interface?
Make a copy of the abstract class source file.
Change "class" to "interface" in the initial declaration.
Change the name (optionally, depends on what you're doing).
Remove the bodies of any methods that are implemented by the class.
Remove the word "abstract" from the other ones.
Remove all private and protected members.
Remove all constructors.
Remove the keyword "public" from the public members.
If you had any code you removed (implemented methods, private or protected stuff), have your original abstract class implement your interface and leave that stuff there.
(Incomplete) Example:
Foo as an abstract class:
public abstact class Foo
{
private int bar;
public static final int SOME_CONSTANT = 42;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
Foo as an interface:
public interface Foo
{
int SOME_CONSTANT = 42;
void doSomething(String s);
}
In my case, as I did have some stuff the old Foo did, I'd probably have AbstractFoo or something:
public abstact class AbstractFoo implements Foo
{
private int bar;
public Foo(b) {
this.bar = b;
}
public abstract void doSomething(String s);
protected int doSomethingElse() {
return this.bar * 2;
}
}
...so that an implementation could use it as a starting point if desired (although with that private bar in there, it doesn't make a lot of sense).
Pattern Adapter might help you.
Imagine, you're have to use SomeClass as TargetInterface
public abstract class SomeClass {
// some code here
public abstract void someMethod();
}
public interface TargetInterface {
public void someMethodBlaBla();
}
And they have different signatures of methods - someMethod() and someMethodBlaBla().
So you're might create such adapter class:
public class Adapter implements TargetInterface {
private SomeClass adaptee;
public Adapter( SomeClass adaptee ) {
this.adaptee = adaptee;
}
public void someMethodBlaBla() {
this.adaptee.someMethod();
}
//delegate all calls to adaptee
}
and somewhere in code you might use both - adapter and instance of abstract class, without interference on current code:
SomeClass abstractClassInstance = ... //get instance of your abstract class
TargetInterface targetInterfaceInstance = new Adapter( abstractClassInstance );
If abstract class does not define any concrete methods, you can even use regular expression for that. From:
public abstract class Abstract {
public abstract void method();
//...
}
to:
public interface Interface {
void method();
//...
}
public abstract modifiers are implicit for interfaces. If the abstract class does define some methods (not all methods are abstract) or have some fields this can't be done (at least easily).