Say that I in Java have 3 classes, wheres the super one has a function named func(), I now make a subclass which overrides this, and a subclass to my subclass, now working on my sub-sub-class how will I call the 'func()' of the sub class, and the superclass?
I tried casting the 'this' "pointer", but Java 'fixes' it at runtime and calls the subsub func().
Edit:
Thanks everyone; 'Skeen is back at the drawing board'.
The best you can do is call super.func() in your subsub class, and have the func() implementation in your subclass also call super.func().
However, ask yourself, if I need knowledge not only of my parents implementation but also my grandparents implementation, do I have a design problem? Quite frankly this is tripping my "Something stinks in the fridge" instinct. You need to re-evaluate why you want to do this.
This isn't possible in Java. And btw. there aren't any pointers in Java.
I would jump on the "something in this design smells funny" train. Normally, you override a method so that it works properly for that specific subclass. If you have code in your parent class that is shared across multiple subclasses, perhaps that code could be moved to a non-overridden method so that it is readily accessible by all children/granchildren/etc.
Could you perhaps flip your design over and use more of a template method approach? (http://en.wikipedia.org/wiki/Template_method_pattern)
The notion behind Template Method is that you have some algorithm in your parent class and you can fill in the pieces that need to be class specific by polymorphic calls into your subclasses. You don't have a ton of detail in your question, but by the sounds of things, I'd really take a good look at your design and see if it makes sense.
Why don't you have func() be not inherited (call it funcBase() or whatever) and then add a wrapper func() function that calls it?
class A{
public void funcBase() {
// Base implementation
}
public void func() {
funcBase();
}
}
class B extends A{
public void func(){
super.func();
}
}
class C extends B{
public void foo(){
super.func(); // Call B's func
funcBase(); // Call A's func
}
}
I have no idea what you're trying to do, but it sounds like your class design is not appropriate for what you want, so you may want separate functions in A instead of trying to sneak your way up the ladder.
This example is the only way to call a "grandparent" super method.
class A{
public void foo(){ System.out.println("Hi"); }
}
class B extends A{
public void foo(){ super(); }
}
class C extends B{
public void foo(){ super(); }
}
This would be a different story if B doesn't override foo().
Another option would be to have a "protected helper" method in the middle class.
class D{
public void foo(){ System.out.println("Hi"); }
}
class E extends D{
public void foo(){ System.out.println("Hello"); }
protected void bar(){ super.foo(); }
}
class F extends E{
public void foo(){ super.bar(); }
}
You can access the superclass methods from within the subclass itself, e.g.
class A {
void foo() {...}
}
class B extends A {
void foo() {...}
void defaultFoo() { super.foo(); }
}
However, you really shouldn't be exposing overridden methods this way, you should write B.foo() in such a way that works fine for A and B. This is where it is a good idea to use super.foo(); like this:
class B extends A {
void foo() {
super.foo(); //call superclass implementation first
... //do stuff specific to B
}
}
Update: In response to your comment on trying to access the implementation 2 levels up, here's a way of doing it.
class A {
void foo() {
defaultFoo();
}
protected void defaultFoo() { ... }
}
class B extends A {
void foo() {...}
}
class C extends B {
void foo() {
defaultFoo();
... //do other stuff
}
}
This is a healthier pattern of coding what you want to do.
You should probably rethink how you are handling your class hierarchy if you need to place a call to a function that is defined two levels up the hierarchy. Consider writing new methods that are implemented by each subclass in a different way.
Related
Is there any way in Java to enforce a subclass or interface implementation to have a constructor with a given signature?
Let's say that I´ve got either:
public interface MyInterface {
// any methods
}
or
public abstract class MyBaseClass {
// any abstract methods
}
Now, is it possible to do anything to require
public class MySubClass extends MyBaseClass {
public MySubClass(String s) { }
}
or
public class MySubClass implements MyInterface {
public MySubClass(String s) { }
}
to always have a constructor that takes a String as it´s only input parameter?
The obvious workaround is to create a factory interface with a method taking a String and inject it where required. Which is not what I would like to do.
Not really, the closest I think you can get is something like:
abstract class B {
public B(String s) {
}
}
public class A extends B {
public A(String s) {
super(s);
}
}
This forces A to implement a non default constructor which must call super(String) but can not prevent the following:
public class A extends B {
public A() {
super("");
}
}
There have been many times where I wished something like this existed, but sadly it doesn't. Even something like what David Soroko suggested wouldn't work because a subclass still wouldn't be forced to have a String constructor - it can just pass any String it likes to super. Simply put, there is no such thing within the Java syntax itself.
I suppose the closest one could get to such a capability is if someone built an annotation processor that allows you to use an annotation like #MustHaveUnaryConstructor(String.class) and then if any subclass does not have such a constructor, it causes compilation to fail and tells you which subclass broke the contract. But I haven't found such a thing and I don't know enough about annotation processing to build one myself. So TL;DR, no, you can't.
Class Base{
public void doThings(){
//some logic that needed by subclass
}
}
Class A extends Base{
public void doThings(){
super.doThings();
doOtherThings();
}
}
What I want is to force A to overwrite doThings() method(there will be error message if not) and call super.doThings(); but doThings() in Base should not be abstract for it has body.
Is there any decent solutions? I found the same question in below link but the accepted answer does not answer it right.
Force SubClasses to #Override method from SuperClass. Method in SuperClass must have body
If you want to make sure that doThings of the base class is called, you should design your class like this:
abstract class Base {
public void doThings() {
// do some things here
...
// make sure subclass does some things too
methodYouMustImplement();
}
abstract void methodYouMustImplement();
}
class A extends Base {
#Override void methodYouMustImplement() {
// do some other things
}
}
This way, A is forced to give a implementation of methodYouMustImplement() and it is guaranteed by design that your code in doThings() is called without the need to remember to call super.doThings().
You could then consider making doThings() final, as Andy Turner suggested.
I think it would be easier to use a construct such as:
public class Base {
public void doStuff() {
doSpecificStuff();
// do base stuff every one has to do
}
abstract void doSpecificStuff();
}
public class WeirdlySpecific extends Base {
public void doSpecificStuff() {
// specific stuff happens
}
}
This does not force WeirdlySpecific to actually implement the doStuff() method, but as long as doStuff() is called as a contract by any caller, each more specific implementation has its own version of events.
A requirement to call the super method is considered an anti-pattern; that aside, the only way you can force a subclass to implement a method is to make it abstract.
If you want super.doThings() to be called first, and then subclass-specific stuff to be run after, turn the problem around:
Make doThings() final
Add an abstract method that is called within doThings().
Something like this:
abstract class Base {
public final void doThings() {
methodYouMustImplement();
// Stuff after subclass-specific implementation.
}
abstract void methodYouMustImplement();
}
class A extends Base {
#Override void methodYouMustImplement() {
doOtherThings();
}
}
The fact that doThings() is final is important to the requirements: this guarantees that the things you want to happen when doThings() is invoked, because no subclass can change this method. If you leave it non-final, subclasses can decide to override doThings(), meaning that methodYouMustImplement() (and any other actions you specify in doThing()) are not necessarily called.
For example, I have many classes that all need a certain method.
In this method, all these classes need one line of code, the remainder of the method is different.
How could I achieve something like this:
void method(){
everybodyDoesThisStuff;
// more individual stuff
// more individual stuff
}
Abstract methods cannot have a body, and if you were not to make it abstract you would then override the method and lose it.
You should make the method that does the "more individual stuff" abstract, not the method itself.
// AbstractBase.java
public abstract class AbstractBase {
public final void method() {
everybodyDoesThisStuff();
doIndividualStuff();
}
abstract void doIndividualStuff();
private void everybodyDoesThisStuff() {
// stuff that everybody does
}
}
// ConcreteClass.java
public class ConcreteClass extends AbstractBase {
void doIndividualStuff() {
// do my individual stuff
}
}
One solution is to require all subclasses to call super.method(). The problem is that there's no way to actually enforce that. Another option is to create a separate method that internally executes the required line and then calls an abstract method:
public final void method() {
callEveryTime();
doMethod();
}
protected abstract void doMethod();
Note that method() is public final so it can be called anywhere but not overridden, whereas doMethod() is protected so it can be overridden but not called outside its package (or subclasses).
You can make a normal method call an abstract method:
void foo(){
// do stuff
bar(); // let the abstract method do the rest
}
abstract void bar();
If you're asking yourself whether you need partial implementations of an abstract method, it's usually time to reconsider the granularity of your design.
Why not extract everybodyDoesThisStuff into a separate method and put it in an Interface?
I have two different interfaces which employ the same methods but dont implement or extend each other. These two interfaces are each extended by another class which implements the interfaces methods
I then have a class which is located in a seperate package which calls the interface methods.
So the class has methods which calls the methods of the interfaces, which are all the same.
public void doThis(){
connection.doThis();
}
public void doThat(){
connection.doThat();
}
public void doAnother(){
connection.doAnother();
}
Now, i want to make the variable connection work for both interface1 and interface2.
My idea was to set connection as a class variable
Object connection
and then to change it type to interface1 or interface2 depending on a condition:
if(this){
//condition which converts connection to type interface1
}
else{
//condition which converts connection to type interface2
}
How do i do this. Can i do this?
I have been given an interface which can not be changed, yet does not implement remote. But my project uses RMI. So i created a 2nd interface in a seperate package which implemets Remote. Thus the reason for 2 different interfaces that do he same thing.
I think it would be easier to make the class containing the method 'connection' public, as it would be accessible from all packages.
This seems like a really weird setup, but I won't question you.
If you know the condition at the method call site (eg, the condition is a constant flag passed to the method), you could parameterize the method with a generic instead. For example:
public class TestGenerics {
public static interface A {
public void a();
}
public static interface B {
public void a();
}
public static class C implements A, B {
public void a() {
System.out.println("a");
}
}
public static <T> T getCAsT() {
return (T) new C();
}
public static void main(String[] args) {
A a = TestGenerics.<A>getCAsT();
B b = TestGenerics.<B>getCAsT();
a.a();
b.a();
}
}
Otherwise, I would try to merge the two interfaces in some way.
In C++ it's possible to change an overridden method's visibility. I find this feature very useful sometimes, for example:
consider you want a class to have some debugging methods, but you don't want them to be visible as public class interface. You could have something like:
class IDebuggable {
public:
virtual void debug(std::string s) = 0;
};
class MyProductionClass: public IDebuggable
public:
void myClassMethod() {}
private:
virtual void debug(std::string) {
// do some debug here
}
};
To do so, when using an object of class MyProductionClass, all I can access is MyProductionClass::myClassMethod() (the production interface).
However, if I want to use it's debugging features, I can do this:
MyProductionClass* obj = new MyProductionClass();
IDebuggable* iface = obj;
iface->debug("Hello World");
I've found in my experience this "feature" quite useful.
In java this is not possible as it's forbidden to change the visibility of an inherited method.
Is there another way I can achieve the above artifact?
Thanks a lot
You cannot reduce visibility of inherited method. This is right. However you can create as many interfaces as you want and make you class to implement these interfaces. Then if your client works with specific interface it "does not have access" to other even public methods.
Here is an example.
public interface Foo {
public void foo();
}
public interface Bar {
public void bar();
}
public class MyClass implements Foo, Bar {
public void foo() {}
public void bar() {}
}
Here is how we use this class:
Foo f = new MyClass();
You can call foo() here and cannot call bsar(). You can however cast Foo to Bar and then use bar() method.
Personally, I hate when people change method visibility this way. I think it's much better to preserver the visibility and expose interfaces, but not the classes themselves, for external users.
Like:
class MyInterface {...}
class MyDebugable {...}
class MyClass : MyInterface, MyDebugable {...}
Give MyInterface to the users and user MyClass internally.
By changing visibility you violate Liskov substitution principle. At the same time your users still can cast to IDebuggable and call your 'private' methods
In Java you can increase method visibility but you can't reduce it when subclassing. This is due to the fact that you may access object via parent class (interface) and all methods defined in parent class should be available to caller.
So the following is possible:
class A {
protected void foo() {}
}
class B extends A {
#Override
public void foo() {}
}
This is (for God's sake) not possible in Java. Furthermore, what you want could be much better achieved by using a logging framework with different configurations for development/production.
Implement a feature discovery like this:
class A {
public final T <T> lookup(Class<T> klazz) {
return map.get(klazz);
}
public A() {
map.put(IDebugable.class, new IDebuggable() { ... };
}
}
A a = ...;
a.lookup(IDebuggable.class).debug();