Lets say I have these two classes, one extending the other
public class Bar{
public void foo(){
}
}
public class FooBar extends Bar {
#Override
public void foo(){
super.foo(); //<-- Line in question
}
}
What I want to do is warn the user to call the super-class's method foo if they haven't in the override method, is this possible?
Or is there a way to know, using reflection that a method that overrides a method of its super-class calls the original method if I pass on the class type to the super?
for example:
public abstract class Bar{
public Bar(Class<? extends Bar> cls){
Object instance = getInstance();
if (!instance.getClass().equals(cls)) {
throw new EntityException("The instance given does not match the class given.");
}
//Find the method here if it has been overriden then throw an exception
//If the super method isn't being called in that method
}
public abstract Object getInstance();
public void foo(){
}
}
public class FooBar extends Bar {
public FooBar(){
super(FooBar.class);
}
#Override
public Object getInstance(){
return this;
}
#Override
public void foo(){
super.foo();
}
}
Maybe even an annotation I can put on the super method so it shows that it needs to be called?
EDIT
Note, its not the super class that needs to call the foo method, it would be someone calling the sub class's foo method, for example a database close method
I would even be happy with making the method "un-overrideable" if it came down to it, but would still like to give it a custom message.
Edit 2
This here is what I wanted in a way:
But it would still be nice to have the above, or even give them a custom message to do something else like, Cannot override the final method from Bar, please call it from your implementation of the method instead
EDIT: To answer the edited, question, which includes:
I would even be happy with making the method "un-overrideable"
... just make the method final. That will prevent subclasses from overriding it. From section 8.4.3.3 of the JLS:
A method can be declared final to prevent subclasses from overriding or hiding it.
It is a compile-time error to attempt to override or hide a final method.
To answer the original question, consider using the template method pattern instead:
public abstract class Bar {
public foo() {
// Do unconditional things...
...
// Now subclass-specific things
fooImpl();
}
protected void fooImpl();
}
public class FooBar extends Bar {
#Override protected void fooImpl() {
// ...
}
}
That doesn't force subclasses of FooBar to override fooImpl and call super.fooImpl() of course - but FooBar could do this by applying the same pattern again - making its own fooImpl implementation final, and introducing a new protected abstract method.
what you could do is something like following
public class Bar{
public final void foo(){
//do mandatory stuff
customizeFoo();
}
public void customizeFoo(){
}
}
public class FooBar extends Bar {
#Override
public void customizeFoo(){
//do custom suff
}
}
foo method made 'final' in superclass so that subclasses can't override and avoid doing mandatory stuff
Related
I'm writing a library, for more readability I want to force user to use nested methods to call the correct functions.
For example this is my class looks like:
public class Foo{
public void methodA(){}
public void methodB(){}
public void methodC(){}
}
What I'm expecting the user:
Foo foo = new Foo();
foo.methodA.methodB();
foo.methodA.methodC();
to call method B & C through calling the methodA as a prefix
After reading your question i think you are asking about Builder Design patten in which every methods return type is same class object and you can make call hierarchy like this.
obj.aMethod().bMethod().cMethod();
in your example just do like this:
public class Foo{
private static final Foo instance = new Foo();
private Foo(){}
public static Foo getInstance(){
return instance;
}
public Foo methodA(){
//Do stuff
return getInstance();
}
public Foo methodB(){}
public Foo methodC(){}
}
Now you can call like objfoo.getInstance().methodA().methodB();
Hope it will help you. To read more about that pattern
To force the user to use methodA to access methodB you could use an inner class.
In methodB you can access the Foo-Object with Foo.this.
public class Foo{
public Bar methodA()
{
// ...
return new Bar();
}
public class Bar {
private Bar() {}; // only methodA can create a Bar object
public void methodB(){}
public void methodC(){}
}
}
This is called as method chaining. You will need to set the return type of all methods as the same as the Class.
public class Foo{
public Foo methodA()
public Foo methodB()
public Foo methodC()
}
Now the client can simply call:
foo.methodA().methodB(), etc.
You can have one "terminal method" i.e. one that does not return a value. For example
public void methodD();
This method will be called last.
foo.methodA().methodB().methodC().method();
This line in itself will be valid as return type is void.
Please look at method chaining/ builder pattern YouTube videos, it will be clear.
I have an abstract super class A with a method doSomething(). A sub-class of A must implement doSomething(), but there is also some common code that should be called every time a subclass calls doSomething(). I know this could be achieved thus:
public class A {
public void doSomething() {
// Things that every sub-class should do
}
}
public class B extends A {
public void doSomething() {
super.doSomething();
// Doing class-B-specific stuff here
...
}
}
There seem to be three issues with this, though:
The method signatures have to match, but I might want to return something in the sub-class methods only, but not in the super-class
If I make A.doSomething() abstract, I can't provide a (common) implementation in A. If I don't make it abstract, I can't force sub-class to implement it.
If I use a different method to provide the common functionality, I can't enforce that B.doSomething() calls that common method.
Any ideas how the methods should be implemented?
What about the following?
public abstract class A {
protected abstract void __doSomething();
public void doSomething() {
// Things that every sub-class should do
__doSomething();
}
}
public class B extends A {
protected void __doSomething() {
// Doing class-B-specific stuff here
...
}
}
The first bullet point however is not so clear. The signature can't match if you want to return something different.
add call back to doSomething()
public class A {
public void doSomething() {
// Things that every sub-class should do
doSomethingMore()
}
}
protected abstract void doSomethingMore()
so all subclusses will have to ipmelment doSomethingMore() with additional actions but external classes will call public doSomething()
For first point alone - you can consider the below answer and for enforcing subclass implementation it can be abstract but calling common code functionality can happen if the base class has some implementation.
Return type can be Object in Base Class and returning null. In SubClass the specific return type can be put as given below.
public class InheritanceTutorial {
static class Base{
public Object doSomething(){
System.out.println("parent dosomething");
return null;
}
}
static class SubClass extends Base{
public Integer doSomething(){
super.doSomething();
System.out.println("child dosomething");
return 0;
}
}
/**
* #param args
*/
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.doSomething();
}
}
I was reading Java SCJP book by Khalid A. Mughal (for JE6), and in topic 7.6 Interfaces and Page number 313, it is given that
A subinterface can override abstract method declarations from its superinterfaces. Overridden methods are not inherited.
I could not quite understand what "Overridden methods are not inherited." means. I tried to do this:
interface A
{
void abc();
}
interface B extends A
{
#Override
void abc();
}
interface C extends B
{
void abc();
}
And I did not get any error. What am I not understanding?
This simply means that overridden methods can have a slightly different signature than the superinterface's methods. For example:
public interface Foo {
Object doSomething(String input) throws IOException;
}
public interface Bar extends Foo {
#Override
String doSomething(String input);
}
As you can see, in the subinterface, I no longer throw a checked exception, and I guarantee that the returned object is a more specific type. The method that did throw a checked exception is not inherited, because it is overridden.
I don't have the context of the entire paragraph, but there's something else related that applies only to implementations and not interfaces, which is that if you override a method without explicitly calling super, the superclass's implementation won't occur.
For example, if I have:
public class Example {
public static class Foo {
public void printSomething() {
System.out.println("Foo");
}
}
public static class Bar extends Foo {
#Override
public void printSomething() {
System.out.println("Bar");
}
}
public static void main(String[] args) {
Bar bar = new Bar();
bar.printSomething();
}
}
This program will simply output:
Bar
but NOT Foo. If I add a call to super.printSomething(), then it will print both.
what is the need of having a rule like this in java :
"a subclass cannot weaken the accessibility of a method defined in the superclass"
If you have a class with a public method
public class Foo {
public void method() {}
}
This method is accessible and you can therefore do
Foo foo = new Foo();
foo.method();
If you add a subclass
public class Bar extends Foo {
#Override
public /* private */ void method() {}
}
If it was private, you should not be able to do
Foo bar = new Bar();
bar.method();
In this example, a Bar is a Foo, so it must be able to replace a Foo wherever one is expected.
In order to satisfy the above statement, a sub class cannot make an inheritable member less accessible. It can however make it more accessible. (This basically only applies to methods.)
What it means
The subclass method cannot have a more restrictive visibity than the superclass method.
For example, if the superclass defined
protected void a() { } // visible to package and subclasses
the subclass can override it with one of
public void a() { } // visible to all
protected void a() { } // visible to package and subclasses
but not
void a() { } // visible to package
private void a() { } // visible to itself
Why it is
Suppose the definition was
class A {
public void a() { }
}
class B extends A {
private void a() { }
}
Now, consider the following code
A instance = new B();
instance.a(); // what does this call?
On the one hand, any B has a publically accessible a method. On the other hand, the a method of a B instance is only accessible to B.
More generally, a subclass(interface) must fulfill the contract of its superclass(interface).
Visibility is only one example of this principle. Another example is that a non-abstract class must implement all methods of any interface it implements.
class Person {
public String name() {
return "rambo";
}
}
// subclass reduces visibility to private
class AnonymousPerson {
private String name() {
return "anonymous";
}
}
It's legal to call the following method with either a Person, or an AnonymousPerson as the argument. But, if the method visibility was restricted, it wouldnt' be able to call the name() method.
class Tester {
static void printPersonName(Person p) {
System.out.println(p.name());
}
}
//ok
Tester.printPersonName(new Person());
this call is legal, because a Person is a AnonymousPerson, but it would have to fail inside the method body. This violates "type safety".
Tester.printPersonName(new AnonymousPerson());
To fulfill the interface contract. Let's say I have an interface, IFlying, as:
public interface IFlying {
public void fly();
}
And I have an implementation that weakens accessibility:
public class Bird implements IFlying {
private void fly(){
System.out.println("flap flap");
}
}
I now have some library function that accepts an IFlying, and calls fly upon it. The implementation is private. What happens now? Of course, it means that the fly method cannot be accessed.
Hence, the accessibility may not be made more restrictive in an implementation.
Here is an example of the issue I've come across:
public interface IFoo { ... }
public abstract class Helper implements IFoo {
public Helper() { ... }
protected abstract X helperMethod();
}
public class Foo extends Helper {
private final String aaa;
#Inject
public Foo(String aaa) { this.aaa = aaa; }
#Override
X helperMethod() { doSomethingUsingWhatsInjected(aaa); }
}
The issue is that when I bind IFoo to Foo like this:
bind(IFoo.class).to(Foo.class).in(Singleton.class);
it appears like helperMethod() is being called before the aaa has been Injected since I'm seeing aaa as null. But if I instead don't use the class Helper and in-line all of its code directly in Foo, guice doesn't struggle.
What's the difference between these two approaches? Why is helperMethod() called before we know from where we're getting the implementation of IFoo? Can we use Helper along with injection?
Are you sure you're not calling helperMethod from within Helper's constructor? You omitted that part from the code you posted, but it would match the behavior you're seeing.
public class Test {
interface IFoo { }
static abstract class Helper implements IFoo {
Helper() { helperMethod(); }
abstract void helperMethod();
}
static class Foo extends Helper {
private final String aaa;
Foo(String aaa) { this.aaa = aaa; }
#Override
void helperMethod() { System.out.println(String.valueOf(aaa)); }
}
public static void main(String[] args) {
// Call helperMethod twice:
// once in the Helper.Helper(), once right here.
new Foo("expected").helperMethod();
// output:
// null
// expected
}
}
The first thing Foo does is implicitly call its superclass constructor, as if you typed super(); this necessarily happens as the very first statement in the subclass constructor. Consequently, this happens even before final variables like aaa are set, so your overridden method in Foo sees aaa as null. As in my example, this is not specific to Guice, but Guice injection can trigger the constructor just like anything else can.
This StackOverflow answer offers a more thorough discussion of this problem.