What is the best java programming practice to call a method on all inherited classes. Consider this pseudo code:
class TopLevel extends (SecondLevel extends Base)
If all these classes have the method 'serializeToString', then how can I call this method throughout the inheritance structure? Te reason for this requirement, is that each class has its own variables it needs to serialize.
Also, there is a further requirement:
Each the class 'TopLevel' and 'SecondLevel' are not asbstract, and will need to be the entry point for serializing their entire inheritance.
Eg,
SecondLevel.serializeToString()
will need to call the method on 'Base' along with itself
And:
TopLevel.serializeToString()
Would need to call the method on both 'SecondLevel' and 'Base'.
Currently, I have the serializeToString method in base, which then calls a method 'addSerialization' on the entire inheritance (and each implementation must call through to super to propagate the call)
While this works, it seems messy in my code to have two methods working to acheive one (simple?) thing.
What would the best way to acheive this be?
The same overriden method in each class in an inheritance structure callling super will give you a chain of calls towards the base class, each one calling the superclass overriden method.
If you don't need to pass extra parameters and the return type is compatible with your logic, you can call super.serializeToString() in each class to call the superclass implementation.
class TopLevel {
#Override public String serializeToString() {
return super.serializeToString() // calls SecondLevel implementation
+ ", topLevelAttribute: 1";
}
}
class SecondLevel {
#Override public String serializeToString() {
return super.serializeToString() // calls Base implementation
+ ", secondLevelAttribute: 2";
}
}
// and so on ...
Now, if above solution doesn't fit you logic, you can't avoid creating another method that is called from the superclass.
class Base {
public String serializeToString() {
StringBuilder sb = new StringBuilder();
appendSerializedTo(sb);
return sb.toString();
}
// can be abstract if there's no implementation here
protected void appendSerializedTo(StringBuilder sb) {
sb.append("baseAttribute: 3");
}
}
class SecondLevel {
#Override protected void appendSerializedTo(StringBuilder sb) {
super.appendSerializedTo(sb); // calls Base implementation
sb.append("secondLevelAttribute: 2");
}
}
// and so on...
Related
Given this class:
abstract class Foo{
public Foo(){...}
public abstract void checkable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
Is there any code I can put in Foo's constructor to make calledWhenCheckableIsCalled get called when checkable is called?
Note: This is a gross simplification of an actual project I am working on.
Edit: I have already implemented a template pattern workaround. I just wondered if there was another way to do this I am missing. (Perhaps using reflection.)
Looks like a template method pattern.
But then you must implement Foo.checkable() and introduce another abstract method to delegate to.
abstract class Foo{
public Foo(){}
public void checkable(){
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
I would also suggest to make checkable() final in this case so that you can be sure that checkable() can not implemented in another way as you expected.
In addition to Brian Roach's comment
The downside is that the protected can be expanded to public in the subclass, so you can't explicitly enforce it.
That's true, but you can prevent a Foo instance from being instantiated if a subclass increases the visibility of doCheckable. Therefore you have to introduce a verification whenever an object is instantiated. I would recommend to use an initializer code so that the verification is executed on every constructor that exists. Then it can not be forgotten to invoke and therefore be by-passed.
For example:
abstract class Foo {
{ // instance initializer code ensures that enforceDoCheckableVisibility
// is invoked for every constructor
enforceDoCheckableVisibility();
}
public Foo() {...}
public Foo(Object o) {...}
private void enforceDoCheckableVisibility() {
Class<?> currentClass = getClass();
while (currentClass != Foo.class) {
try {
Method doCheckableMethod = currentClass.getDeclaredMethod("doCheckable");
if (Modifier.isPublic(doCheckableMethod.getModifiers())) {
throw new RuntimeException("Visibility of "
+ currentClass.getSimpleName()
+ ".doCheckable() must not be public");
}
} catch (SecurityException | NoSuchMethodException e) {}
currentClass = currentClass.getSuperclass();
}
}
}
Since the check is implemented using reflection the downside is that it is only checked at runtime. So you will not have compiler support of course. But this approach let you enforce that an instance of a Foo can only exist if it fulfills your contract.
No, the constructor will get invoked once during the object initialisation. You can however get your subclass that provides the implementation to call the method in the super class:
class Bar extends Foo {
// implementation of abstract method
public void checkable(){
super.calledWhenCheckableIsCalled(); // call to parent's method
...
}
}
EDIT
You could achieve this with aspects. Using an aspect you can intercept each call to a method by referring to the abstract parent method. This leaves you free from interfering eith the child code. Your calledWhenCheckableIsCalled code would then become part of the intercepting code.
abstract class Foo {
// use pointcut to intercept here
public void checkable();
}
There is no way as you are forcing that method to implement in child.
An awkward suggestion will be know from child implementation. I mean there is no clean way AFAIK
abstract class foo {
public abstract void bar();
public void moo() {
System.out.println("some code");
this.bar();
System.out.println("more code");
}
}
now if moo is called, the underlying implementation of bar will be used, it is just a small paradigm shift from what you want.
so your end user would call moo instead of bar, but he still needs to implement bar
Nope, an abstract method doesn't have a body. You could, however, chain your method like this:
abstract class Foo {
void callMeInstead() {
// do common
callMeImplementation();
}
abstract void callMeImplementation();
}
It looks to me like you're looking for the template pattern:
public abstract class Template {
public final void checkable() {
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
private void calledWhenCheckableIsCalled() {
System.out.println("checkable was called");
}
}
Now, each time checkable() is called, calledWhenCheckableIsCalled() is also called. And the suclass must still provide the actual implementation of checkable(), by implementing the doCheckable() method.
Note that making checkable() final prevents a subclass from overriding it and thus bypassing the call to calledWhenCheckableIsCalled().
Say I have a base class with a pair of methods (called foo and bar). In most cases, they don't need to be overriden, but in some cases, they do. I want to make sure if one of them is overriden, then the other one must also be overriden, or it is an error.
What tricks could I use to ensure either none of the two methods is overriden, or both of them are overriden?
This has proven to be an interesting thought exercise. The best solution I could come up with is as follows:
Declare an interface for your methods:
public interface YourInterface {
public void methodOne();
public void methodTwo();
}
Create a base class that implements these methods by delegating to an inner YourInterface instance. Take a parameter in your protected constructor that overrides the default behaviour:
public abstract class Base implements YourInterface {
private YourInterface override;
protected Base(YourInterface override) {
this.override = (override == null) ? new BaseImplementation() : override;
}
#Override
public final void methodOne() {
override.methodOne();
}
#Override
public final void methodTwo() {
override.methodTwo();
}
// This is the default implementation
private static class BaseImplementation implements YourInterface {
#Override
public void methodOne() {
System.out.println("Original one.");
}
#Override
public void methodTwo() {
System.out.println("Original two.");
}
}
}
The two methods are final in the base class, so subclasses can't just override one of them.
Not necessarily an elegant or advisable solution.
There is no easy way to do this. A method exists, but I don't know if it will really meet your needs. I think what you should really consider is why you want this, and if a different construct (abstract classes? AOP? Something else?) will meet your design needs better.
You can write a snippet to quickly determine if a method has been overridden:
String declaredIn = obj.getMethod("myMethod").getDeclaringClass();
This will return the current class name if overridden, or a/the base class name if not.
If you require any subclasses to call super.foo and super.bar in foo and bar (which you can enforce with stuff like non-parameterless constructors), you can enforce this in the base methods: check if the declaring class is the same for both methods, and throw an exception.
A similar problem exists in Object, with the equals(Object) and hashCode() methods.
If you want to absolutely ensure that an implementation is provided for either both or neither, Duncan's answer provides an elegant solution for this by wrapping the functionality in an interface to be passed in during construction - it guarantees either the default implementation for both methods, or a different implementation for both.
However, if your case is more like the one in Object, where they dont' need to be overridden, but just satisfy a very specific contract, then clear documentation on what that contract is will work better, allowing developers to satisfy the contract the way they determine is best.
If you had one method and you wanted to make sure it was overridden, I think something like this would work:
public class C {
public void foo() {
if (this.getClass() != C.class)
throw new RuntimeException ("foo was not overridden for class " + this.getClass().getName());
...
But making sure two methods are either both overridden or not overridden seems much trickier. How about this: Instead of having child classes override foo and bar, make foo and bar final methods, and provide protected "implementation" methods in which classes must override either both or neither. Then:
public class C {
private boolean fooCalled = false;
private boolean barCalled = false;
private boolean fooDefault = false;
private boolean barDefault = false;
public final void foo() {
fooCalled = true;
fooImpl();
checkOverrides();
}
public final void bar() {
barCalled = true;
barImpl();
checkOverrides();
}
private void checkOverrides() {
if (this.getClass() != C.class && fooCalled && barCalled &&
(fooDefault != barDefault))
throw new RuntimeException ("foo or bar was overridden without the other for class " + this.getClass().getName();
}
protected void fooImpl() {
fooDefault = true;
// the rest of the default implementation
}
protected void barImpl() {
barDefault = true;
// the rest of the default implementation
}
}
We can't check until both foo and bar have been called at least once each (and if either of those is never called, then it shouldn't matter whether it's overridden or not). Once both have been called, we will know whether or not each method (the "Impl" version) was overridden, because a flag will be set when the default implementation is called. Then we can do whatever checking we wish with the information.
This will fail if an overriding fooImpl calls super.fooImpl() (similarly for bar), but my guess is that if you expect this to happen, then the requirement that both be overridden if one is probably doesn't make sense. If it's still necessary, a separate protected default implementation method could be provided that doesn't set the fooDefault flag, and clients will just have to be careful to use it instead of the super method.
Having written all this, it's hard for me to imagine that a solution like this would be really necessary. Maybe you have a case where it's worthwhile.
You can add a contructor to your class and use reflection to check in wich class the methods are overrided and throw an Error if it's only one overrided.
Can be something like this (test is the name of the base class that I used):
public test() {
Class clazz = this.getClass();
try {
Method m = clazz.getMethod("foo", new Class[]{});
Class cFoo = m.getDeclaringClass();
m = clazz.getMethod("bar", new Class[]{});
Class cBar = m.getDeclaringClass();
if (cFoo.equals(test.class)&&!cBar.equals(test.class)) throw new Error();
if (!cFoo.equals(test.class)&&cBar.equals(test.class)) throw new Error();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
Have a marker interface #OverrideRequired with target METHOD
Annotate needed methods with #OverrideRequired.
Use Reflection to write validateOverrideRequired(Class...classes) which throws a RuntimeException if the methods with annotations #OverrideRequired are not overridden in the subclass? Call it once per build as a rule.
The above is just a concept; not sure of the implementation.
But an interesting question & equally interesting answers (rest) from the group.
Can't you put both of them into an interface and let the client decide whether to implement them or not.
This way either both of them are overridden if some implements this interface or not if no one implements
Is there some type of #annotation, or other method, in Java to enforce method extension, instead of overriding?
To be specific, let's say I have a class Foo:
class Foo {
public void bar(Thing thing) {
// ...
}
}
Is there a way I can enforce, at compile time, that any class X that extends Foo, and also overrides bar, makes a call to super.bar(thing) first?
No, you have to explicitly write it.
Side note for constructors: the superclass' nullary constructor will be implicitly called when instantiating the subclass, however many parameters the latter's constructor has.
You could declare bar to be final, then call an abstract method from bar, which would force subclasses to implement an "extension".
abstract class Foo {
public final void bar(Thing thing) {
barImpl(thing);
overrideMe(thing);
}
private final void barImpl(Thing thing) {
// Original implementation of "bar" here.
}
protected abstract void overrideMe(Thing thing);
}
EDIT
I've changedoverrideMe from public to protected so users of Foo can't just call overrideMe instead of bar.
Generally, what you can do is to create a final method, that calls the extendable one.
class Foo {
#Override
public final void bar(Thing thing) {
// super code comes here
this.doBar(thing);
}
public abstract void doBar(Thing thing);
}
When you call
foo.bar(thing);
your super code runs first, then the code from the child class.
This way you can protect your full bar logic, and allow only certain parts to be extended/reimplemented.
Also, it allows you to postprocess the result, or to break up your code to certain subtasks.
While you cannot force code to call up to its superclass at compile time, it's not too hard to detect at run time when code does not call up to the superclass.
class Foo {
private boolean baseCalled;
public final void bar(Thing thing) {
baseCalled = false;
barImp(thing);
if (!baseCalled) {
throw new RuntimeException("super.barImp() not called");
}
}
protected void barImp(Thing thing) {
baseCalled = true;
. . . // base class implementation of bar
}
}
Note that this extends to multiple levels of inheritance without further elaboration. The method works particularly well for methods that are called from within Foo; in those cases, you can often forgo the final qualifier and redirection to an implementation method, and just define the base class method to set the flag. Clearing the flag would be done at each point of invocation.
The above pattern is used extensively in the Android framework. It doesn't guarantee that super.barImp was called as the first thing in subclass overrides; just that it was called.
You can try to use #AroundInvoke annotation, if you are using EJBs.
By using reflection, you can find the same method in your parent class, and yo can invoke it with the same parameters as the original method was called.
Note, that in this case you must avoid super.bar(thing) calls, otherwise they would be called twice.
I'm fairly new to OO programming specifically with Java. I have a question pertaining to inheritance.
I have a printing method that I'd like to be common among subclasses. The code in the print method is usable for all subclasses except for a response object that is specific to each individual subclass.
I'm thinking that i need to probably just override the method in each subclass providing the specific implementation. However it feels like there would be a slicker way to keep the common method in the super class and while somehow supplying the specific response object based on the subclass accessing it.
Any thoughts? Sorry if this seems elementary....
You will want an abstract base class that defines what is done, while the child classes define how it is done. Here's a hint as to how such a thing might look
public abstract class BaseClass{
public final String print(){
return "response object: " + responseObject();
}
protected abstract Object responseObject();
}
This is loosely related to the Template Method pattern, which might be of interest to you.
You are absolutely right, there is a better way. If your implementations share a great deal of code, you can use template method pattern to reuse as much implementation as possible.
Define a printReponse method in the superclass, and make it abstract. Then write your print method in the superclass that does the common thing and calls printResponse when needed. Finally, override only printResponse in the subclasses.
public abstract class BasePrintable {
protected abstract void printResponse();
public void print() {
// Print the common part
printResponse();
// Print more common parts
}
}
public class FirstPrintable extends BasePrintable {
protected void printResponse() {
// first implementation
}
}
public class SecondPrintable extends BasePrintable {
protected void printResponse() {
// second implementation
}
}
You can do something like this
public class A {
protected String getResponse(){ return "Response from A"; }
public void print(){
System.out.println( this.getName() );
}
}
public class B extends A {
protected String getResponse(){ return "Response from B"; }
}
A a = new A();
B b = new B();
a.print(); // Response from A
b.print(); // Response from B
i.e. you dont need to override the print method, just the getResponse
Why can't Java classes have abstract fields like they can with abstract methods?
For example: I have two classes that extend the same abstract base class. These two classes each have a method that is identical except for a String constant, which happens to be an error message, within them. If fields could be abstract, I could make this constant abstract and pull the method up into the base class. Instead, I have to create an abstract method, called getErrMsg() in this case, that returns the String, override this method in the two derived classes, and then I can pull up the method (which now calls the abstract method).
Why couldn't I just make the field abstract to begin with? Could Java have been designed to allow this?
You can do what you described by having a final field in your abstract class that is initialised in its constructor (untested code):
abstract class Base {
final String errMsg;
Base(String msg) {
errMsg = msg;
}
abstract String doSomething();
}
class Sub extends Base {
Sub() {
super("Sub message");
}
String doSomething() {
return errMsg + " from something";
}
}
If your child class "forgets" to initialise the final through the super constructor the compiler will give a warning an error, just like when an abstract method is not implemented.
I see no point in that. You can move the function to the abstract class and just override some protected field. I don't know if this works with constants but the effect is the same:
public abstract class Abstract {
protected String errorMsg = "";
public String getErrMsg() {
return this.errorMsg;
}
}
public class Foo extends Abstract {
public Foo() {
this.errorMsg = "Foo";
}
}
public class Bar extends Abstract {
public Bar() {
this.errorMsg = "Bar";
}
}
So your point is that you want to enforce the implementation/overriding/whatever of errorMsg in the subclasses? I thought you just wanted to have the method in the base class and didn't know how to deal with the field then.
Obviously it could have been designed to allow this, but under the covers it'd still have to do dynamic dispatch, and hence a method call. Java's design (at least in the early days) was, to some extent, an attempt to be minimalist. That is, the designers tried to avoid adding new features if they could be easily simulated by other features already in the language.
Reading your title, I thought you were referring to abstract instance members; and I couldn't see much use for them. But abstract static members is another matter entirely.
I have often wished that I could declare a method like the following in Java:
public abstract class MyClass {
public static abstract MyClass createInstance();
// more stuff...
}
Basically, I would like to insist that concrete implementations of my parent class provide a static factory method with a specific signature. This would allow me to get a reference to a concrete class with Class.forName() and be certain that I could construct one in a convention of my choosing.
Another option is to define the field as a public (final, if you like) in the base class, and then initialize that field in the constructor of the base class, depending upon which subclass is currently being used. It's a bit shady, in that it introduces a circular dependency. But, at least it's not a dependency that can ever change -- i.e., the subclass will either exist or not exist, but the subclass's methods or fields can not influence the value of field.
public abstract class Base {
public final int field;
public Base() {
if (this instanceof SubClassOne) {
field = 1;
} else if (this instanceof SubClassTwo) {
field = 2;
} else {
// assertion, thrown exception, set to -1, whatever you want to do
// to trigger an error
field = -1;
}
}
}