java class A extends class B, and method override - java

public class A {
protected ClassX a;
public void foo() {
operations on a;
}
}
public class B extends A {
private ClassY b; // ClassY extends ClassX
#Override
public void foo() {
//wanna the exact same operation as A.foo(), but on b;
}
}
Sorry for such a not clear title.
My question is: in class B, when I call foo(), and I want the exact same operation as class A have on a. How do I achive that and without duplicate the same code from A?
If i leave out foo() in class B, would it work?
Or whats happening when I call super.foo() in foo();

Since ClassY extends ClassX, then you can remove private ClassY b from class B. Then you can just set your instance of ClassX to the a instance variable. This allows foo() to be inherited in class B, but still use the same logic and instance variable.
public class A {
protected ClassX a
public void foo() {
// operations on a;
}
}
public class B extends A {
// do something to set an instance of ClassY to a; for example...
public void setClassY(ClassY b){
this.a = b;
}
}

It sounds like ClassX and ClassY would have a common interface (if they have the same methods you want to call on earch, at least). Have you considered making foo() take in an object of the type of the common interface?
public class A {
private ClassX a;
protected void foo(ClassXAndClassYInheritMe anObject) {
operations on anObject;
}
public void foo() {
foo(a);
}
}
public class B {
private ClassY b;
#Override
public void foo() {
foo(b);
}
}

Don't define the foo() method in B if you want the same operation as that in A. If you want a different operation as A, override the foo() method in B. If you want to extend the foo() method in B so that it first does the operation in A and then in B, then call super.foo() at the top of the method; if you want the operation in A to come after the one in B, then call super.foo() at the end of the method foo().

You can do super.foo() inside your overrided method.

Related

Making abstract an overridden method

Here's something I quite understand:
abstract class A {
public void foo() {
System.out.println("a");
}
}
abstract class B extends A {
#Override
public abstract void foo();
public void bar() {
super.foo();
foo();
}
}
class C extends B {
#Override
public void foo() {
System.out.println("c");
}
}
public static void main(String[] args) {
new C().foo();
new C().bar();
}
new C().foo() prints c to the console, while new C().bar() prints a then c.
Calling super.foo() is illegal in the #foo() implementation of the C class.
I don't have a clear question, but if anyone could give a complete explanation of what is going on with the foo method, it may be interesting I think.
A is super class for B, so calling super.foo() inside B calls method defined in A, and calling foo() inside the same class will invoke its own implementation that should be delivered by any subclass.
You cannot use super.foo() within C class because it is defined as abstract in B and cannot be invoked directly.

Call base method on generic object of derived class

Trying to add a base interface with method so all derived classes have to implement the method or use default method. What's the best way to going about getting this method callable? See comment in code block below.
public interface IA{}
public interface IB{
public Integer doWork();
}
public interface IC extends IB{
}
class B implements IB{
Integer doWork(){
return 2;
}
}
class C extends B implements IC{
#Override
Integer doWork(){
return 7;
}
}
//What do I need to do to cast clazz to an object so I can call the derived class' doWork method?
private Integer newClient(Class<T> clazz){
((B) clazz).doWork();
}
Ended up finding a solution:
B.class.cast(clazz);
As for how to ensure you call the derived class' method that overrides the base, that is a native behavior of Java.
Example Program:
public class Foo {
static class A {
int get() { return 0; }
}
static class B extends A {
#Override
int get() { return 1; }
}
public static void main(final String[] args)
{
A a = new A();
B b1 = new B();
A b2 = new B();
printA(a);
printA(b1);
printA(b2);
}
public static <T extends A> void printA(T bObj) {
System.out.println(bObj.get());
}
}
Output:
0
1
1
Note that the output returned from b2::get()::int is the same as b1::get()::int, even though b2 is type A and b1 is type B. This is because even though we only have a reference to the A class in b2, the object implementation is still B.
It seems that you only want to know how to instantiate the Class. Assuming it has a default constructor you can do it this way:
private Integer newClient(Class<B> clazz){
try {
((B) (clazz.getConstructor().newInstance())).doWork();
} catch ...
}

Inheritance - What method is being called?

I have a class A that extends a class B.
A is defined like this, it also overrides a method of B:
class A extends B
{
public A() {
super();
}
#Override
public void doSomething(){
//does something
}
}
B is defined like this:
public class B
{
public B(){
doSomething();
}
public void doSomething(){
//does something
}
}
So if I initialize an object of A, the constructor calls the one of the superclass that calls the method doSomething(). But which one will be executed? B's implementation or the overriden one in A?
That is a common bug, only call final methods in constructor, the method from A will be called.
Btw Sonar(if you have it) will trigger a rule here saying that you should not call polymorphic methods inside a constructor.
If the class Overrides a method, then the overriden method will be called. Try the example below:
public class A {
void doSomething() {
System.out.println("a");
}
}
public class B extends A {
#Override
void doSomething() {
System.out.println("b");
}
}
A a = new B();
a.doSomething(); // will print "b"

Calling the constructor of an abstract class

Say I have the following class structure:
public class A{
A(int a){
...
}
}
abstract class B extends A{
}
public class C extends B{
C(int a){
super(a);
}
}
This code isn't valid in the sense that myMethod will not call A's constructor. Is there a way to do this?
What I ultimately want to do, is add functionality to a set of classes without affecting their functionality. All these classes currently extend a common class (runtimeException), so I was thinking of adding an intermediary abstract class.
(edit: the code in C shouldn't be a method, it was meant to be a constructor)
You will not be able to declare class B like you wrote. To create an instance of B you'll need to call A constructor:
public abstract class B extends A {
public B() {
super(10); //or other number
}
}
public class C extends B {
public C(int a) {
super();
}
}
In other words, you always call constructor of "previous level", whether the class is abstract or not.
In order to avoid this strange number 10 I wrote and missing int parameter of C constructor, I suggest adding to child class constructor at least all parameters parent class constructor requires for any extends pair of classes.
What I've seen commonly is a pattern like this:
public class A{
A(int a){
...
}
}
abstract class B extends A{
B(int a) {// "proxy" constructor"
super(a);
}
}
public class C extends B{
C(int a) {
super(a);
}
void myMethod(int a){
// super(a); <- note this is invalid code, you can only call this from the constructor
new C(0); // <-- this is valid
}
}
Granted, it's a bit verbose and boilerplate-y, but it allows you to avoid duplicating any functionality

syntax to call un-overridden method

I have
public class D extends B
{
public void method() {}
}
public class B
{
public void method() {}
public void anotherMethod() { method(); }
}
In the above, if you hold an instance of D, say d, d.anotherMethod() results in calling D.method.
Is there a syntax in Java to call B.method() from inside anotherMethod()?
No, there isn't. The derived class would have to contain a call to super.method().
If B wants to prevent subclasses from overriding method(), it should declare method() as final.
You still can call the super method by explicitly using super like this this:
public class D extends B{
public void method() {}
public void anotherMethod() { super.method(); }
}
The only thing that is required is for you to override anotherMethod().
Another way is thinking like this. You want anotherMethod to call B method() so:
public class D extends B{
public void methodInternal() {}
}
public class B{
public final void method() {
//...
methodInternal();
}
public void methodInternal() {}
public void anotherMethod() { method(); }
}
Here the user can create his own version of method() by overriding methodInternal(), but still the behavior of the original method() is intact.
You can make method() static in B and then call it as B.method() from the instance methods where it is needed (you may need to rename the static method if you want to use the name for the instance method).
At least that's what I do in similar situations.
Maybe you should also reconsider your design.

Categories