java inheritance misunderstanding - java

The first question is inside the code. The second question is why static methods can't be overridden to be non-static methods? The third is why can't static and abstract go together?
class A {
public void display() {
System.out.println("Display of Class A called");
}
}
class B extends A {
public void display() {
System.out.println("Display of Class B called");
}
}
class C extends B {
public void display() {
System.out.println("Display of Class C called");
super.display(); // calls B's Display
// Is there a way to call A's display() from here?
}
}

[B] // Is there a way to call A's Display from here???[/B]
No, you can't go two steps up in the class hierarchy. You could implement and call a method in B which would invoke the A implementation.
why static methods can't be overridden to be non-static methods
static methods are associated with a class. Polymorphism (and thus overriding) is a concept that applies to objects and therefore does not apply to them.
why can't static and abstract go together
For the same reason given above. An abstract method is a method that should be implemented in a sub class because the sub class inherited it. Since a sub class does not inherit a static method, a static method cannot be abstract.

First question: no you can't call the bass class's bass class directly, since in class C's view, it has no idea that class B has a bass class and it's class A. All that's know by C is that it has a base class, and it's B.
Second question: static methods are simply a neat way to organize global methods. There's no inheritance. You just put that method to a class so when you write code to call it, you know where to locate it.
Third question: abstract means "this is what the class to do, here are some basic functionality, but I cannot finish this; inherit me and finish whatever is left to get it working". As mentioned earlier, static method is just a way to put methods that "stand by themselves", requires no initialization and no context. The two does not go together.

Related

Is it possible for a superclass object to refer a subclass member method which is not inherited?

In dynamic method binding a superclass reference can only call a subclass method which is inherited and overrode by it. However, the otherwise can be implemented.
abstract class in
{
abstract void print();
}
class a extends in
{
String name=this.getClass().getSimpleName();
void show()
{
System.out.println("class "+name);
}
void print()
{
show();
}
}
class Main
{
public static void main(String args[])
{
in x;
x = new a();
x.print();
}
}
Here, it prints successfully
class a
Also getClass() returns the subclass name instead of superclass name as this refers to the superclass object in main method.
A parent object reference is just constrained by the methods that it has in its class definition. If those methods are overridden by subclass, and at run time, if the actual object referred by the parent reference is of subclass type, then that overridden method is invoked. It doesn't matter if the overridden method invokes methods that are not originally present in the parent class or accesses the variables that are not present in the parent class.
This is what polymorphism is all about. It is by design meant to be this way as it makes program extension easier in case if we have different specific inheritance hierarchies where the parent class need not know the exact implementation of certain methods and can make things implemented by the subclasses as some sort of contract.
Future is unknown A developer writing a class A.java today can never predict in future the names or signatures of the methods which any other developer may include in his class extending A.java. Also such classes may be numerous with each having separate methods.
Base class should never be coupled with its sub classes. It must not care about how the sub classes are implemented.
Although it is not recommended but still if you wish to invoke the method defined in one of the sub class you may do it by typecasting like below.
public class Parent {
public class someMethod(){
if( this instanceof Child1){
((Child1)this).someAdditionalMethod();
}
}
}
public class Child1 extends Parent{
public class someAdditionalMethod(){
}
}

Override Base class methods in different class other than derived class

I am newbie to Java concepts. I'm wondering what is the way to implement the following logic.
Consider the following base class:
public class A {
public methodA() {
....
}
public methodB() {
..
}
}
The derived class:
public class B extends A {
// some B's stuff
// Overriding base class method
public methodA() {
// Some common stuff
super.methodA()
}
// Overriding base class method
public methodB() {
// some common stuff
super.methodB()
}
}
We don't have the access to modify base class methods. So we overriding the class and making changes.
Since overriding base class methods are in huge numbers, I want to move it to a separate class so that my derived class B is clean.
Questions:
Is there is any way to override the base class methods in a seperate class and link it to derived class.
There is same set of conditions is executed in overriding the super class methods. Is there is anyway to have common conditions to be executed before calling super class methods.
Note:
I can create a class C extends base class A and override the methods and then make class B to extend Class C.
But, I wondering if that is the proper way or is there is any other way to implement the above logic.
Any help is greatly appreciated.
Thanks in advance.
Q: Is there is any way to override the base class methods in a seperate class and link it to derived class?
A: By definition, "overriding a method" must be done in some child class.
Q: Since overriding base class methods are in huge numbers, I want to move it to a separate class so that my derived class B is clean.
A: I'm not even sure what this means ... but it kind of sounds like you simply want a child class ... one that's less complex. Perhaps "public class C extends B"?
Or maybe you even want to define an "interface", and have A (or some subclass) implement that interface?
Is there is any way to override the base class methods in a separate class and link it to derived class.
No, the overrides must happen in B. However, since you have full control of B's implementation, you can make another class, HelperB, put overrides there, and use it as B's base class:
class A {
// A's methods
}
class HelperB extends A {
// Overrides of A's methods
}
class B extends HelperB {
// B's methods
}
This would keep B's logic free of overrides of A's methods.
Is there is anyway to have common conditions to be executed before calling super class methods?
Move common logic into separate methods inside A. Make these methods protected, and use it from inside A's implementations. Now you can reuse the same computations in B, as well as in all other classes derived from A:
class A {
// Evaluates a common condition
protected boolean condition1() { ... }
// Uses a common condition in the base class
public void method1() {
if (condition1()) {
...
}
}
}
class B extends HelperB {
public void method1() {
// Some B-specific code
// Uses a common condition in the base class
if (condition1()) {
...
}
// More B-specific code
}
}
Why don't you create another class C and extend it to ContextWrapper and place all your methods in it. To use the methods in Class C, initialize an object of class C in either Class A or B and call it's methods through the object of C. Make sure the methods are public in Class C.

Java: Force base class to use base class method instead of overriden method

I have a Base class method, that I want to override in a Derived class.
The derived class method should be called whenever the method with the same name is accessed from "outside" or from the derived class. When acessing the method from inside the base class, I want the base class method to be used. Consider the following code:
public class TestBaseMethod
{
static class Basic {
public Basic()
{
Basic.this.doSomething(); // <<---- This should call Basic version
}
public void doSomething()
{
System.out.println("Doing something old");
}
}
static class Derived extends Basic {
Object ressource = new Object();
#Override
public void doSomething()
{
System.out.println("Doing something completely new");
// ressource.toString(); // <<---- explosion
}
}
public static void main(String[] args)
{
Basic d = new Derived();
System.out.println("-------------------------------");
d.doSomething(); // <<---- This should call Derived version
}
}
I want the following output:
Doing something old
-------------------------------
Doing something completely new
But it produces this output:
Doing something completely new
-------------------------------
Doing something completely new
I thought that explicitly stating the base class name in Basic.this.doSomething(); should do that trick, but apparently it does not.
Obviously, I could declare a variable of type Basic inside a Derived class instead of Deriving, but that kind of defeats the idea that the Derived class "is-a" Basic class and would force me to write oneline-redirection methods to obtain the same interface.
Here is why I want to do that:
When writing base classes, I want to use methods where I have the guarantee that inside the base class, the methods that I wrote are used, because I do not want deriving classes to interfere with base class internals. To me, it makes sense from an encapsulation standpoint, but maybe I am wrong?
The Basic#doSomething() method can be called from the Basic() constructor.
If the Derived#doSomething() method uses ressources from Derived, then those ressources will only be available after Derived construction.
However: Derived construction finishes AFTER the superclass construction, which means that when Derived is constructed, the Derived#doSomething() is called in the Basic() constructor and it will access uninitialized data.
Is there a way around this?
Calling veritable methods from a constructor is a bad practice, more could be found here: On invoking overridable method from constructors
As for enforcing to call the base class method - it's impossible.
Make an inner method in Basic for doSomething and call that directly:
static class Basic {
public Basic()
{
doSomethingImpl();
}
public void doSomething()
{
doSomethingImpl();
}
private void doSomethingImpl()
{
System.out.println("Doing something old");
}
}
What you want to do is bad, from a design point of view. A good design would be to declare two separate methods, one overridable and the other not (either final or private).

How is inheritance implemented in Java?

How exactly is inheritance implemented in Java? For example, consider this:
class A {
public void foo() {
System.out.print("A");
}
}
class B extends A {
...
}
class Test {
public static void main(String[] args) {
B test = new B();
test.foo(); // how is foo() called?
}
Below the line, would the compiler just dump the definition of A.foo() into the body of class B? Like
class B extends A {
...
public void foo() {
System.out.print("A");
}
}
Or is foo somehow looked up in class A and called there?
This may be able to assist you, explanation from the book Ivor Horton's Begining Java 7
I said at the beginning of this chapter that a derived class extends a base class. This is not just jargon — it
really does do this. As I have said several times, inheritance is about what members of the base class are
accessible in a derived class, not what members of the base class exist in a derived class object. An object of
a subclass contains all the members of the original base class, plus any new members that you have defi ned
in the derived class. This is illustrated in Figure 6-3.
Method bodies aren't copied in the undefined method body of a subclass. Instead, when you call
B test = new B();
test.foo();
It will look trough its hierarchy, going up a level every time it can't find an implementation.
First it will check B which has no implementation. One level above that there's A which does, so it will use that one.

Can I know the extending class from the super class in Java?

I have the following classes.
public class Super{
public static void useSubClass(){
//I want to access the sub class object here, how.
}
}
public class Sub1 extends Super{
}
public class Sub2 extends Super{
}
I want to access the sub-class object from a static method in super-class. i.e. When I call Sub1.useSubClass() the method has access to Sub1.class and when I use Sub2.useSubClass(), I can access the Sub2.class.
Is there any way to access the sub-class object from super-class.
In general, you cannot do that from a superclass (and shouldn't!) because you won't know (and shouldn't assume anything about!) what classes will inherit from your superclass.
Depending on exactly what you want to do, there are alternatives, such as:
Use the template pattern to define "filler methods" that your subclasses must implement; these filler methods will be called by the template method in your superclass.
Define methods to be overridden by your subclass.
Define interfaces to be implemented by your subclass.
Update: As #JB Nizet has pointed out, I might have misread the question.
Here's something (very similar to the Observer Pattern) you can do if you wish to access subclasses from the static method in your superclass:
Define a static listener list in your superclass, call it List observerList
In the constructor of your superclass, add the class instance itself to that static observerList
For all subclasses, it is their responsibility to call super() from their constructors in order to register themselves to observerList (and unregister in deconstructor)
Then in your superclass's static useSubClass() method, you can iterate through that list of subclass instances, find the particular one you care about (maybe specified by some argument), and then do something with it.
Static methods are not inherited, and calling Sub2.useSubClass() is strictly equivalent to calling Super.useSubclass().
There is no way to get this information, because it doesn't exist. The compiler allows calling Sub2.useSubclass(), but translates it into Super.useSubclass().
public static void useSubClass(Super sub) {
if (sub instanceof Sub1) {
// Do something
} else if (sub instanceof Sub2) {
// Do something else
} else {
// Something else is extending Super
}
}
However, a better question is why? Can't you simply override the method in your subclass?
No you cannot because the super-class cannot know the methods of the sub-classes.
You should consider to create a new class which sees both super-class and sub-classes and implement the static method inside this new class
For the record, you could do this in Python, using class methods:
class super(object):
#classmethod
def usesubclass(cls):
print cls
class sub1(super):
pass
class sub2(super):
pass
Using this code, you could call sub1.usesubclass() or sub2.usesubclass(), and that would print the representations of the sub1 and sub2 classes, respectively:
>>> sub1.usesubclass()
<class '__main__.sub1'>
>>> sub2.usesubclass()
<class '__main__.sub2'>
Java, however, does not support such mechanisms, unfortunately. When you compile Sub1.useSubClass() in your example, the compiler will simply use Sub1 as the basic namespace to look up the the useSubClass() method in Super, but no information on that is actually compiled into code. In the resulting bytecode, the call is simply one directly to Super.useSubClass() and nothing more.
I sympathize with your plight, but Java is what it is. The closest thing you could come, I think, would be the following code:
public class Super {
public static <T extends Super> void useSubClass(Class<T> sub) {
}
}
And then call that method explicitly as either Super.useSubClass(Sub1.class) or Super.useSubClass(Sub2.class).
I figured something out. It works if implemented with care.
/** SuperClass.java **/
public abstract class SuperClass {
public static void printClass(){
System.out.println(new ImplementingClassRetriever().getCallingClass());
}
static class ImplementingClassRetriever extends SecurityManager{
public Class getCallingClass() {
Class[] classes = getClassContext();
for (Class clazz : classes) {
if (SuperClass.class.isAssignableFrom(clazz) && clazz != null
&& !clazz.equals(SuperClass.class)) {
return clazz;
}
}
return null;
}
}
}
/** Main.java **/
public class Main{
public static void main(String[] args) {
Sub.printClass(); //this does not work
Sub.testStaticCall(); //this works!! :)
}
}
class Sub extends SuperClass{
public static void testStaticCall(){
Sub.printClass(); //calling the method in the super class
}
}
This is just a toy example. The super class contains a static class that contains a method to retrieve the calling class.
In the subclass I have another static method which calls the superclass's method for printing the class name.
The Main class/function contains two calls to Sub's inherited and locally implemented method. The first call prints null, because the calling context (i.e. Main) is not a subclass of Super However the delegate method in Sub works because the calling context is now a subclass of SuperClass and hence the calling class can be determined.
Although You can create a reference to the super class and point it to any sub-class. This can also be done dynamically during run-time. This is a way of run-time polymorphism.

Categories

Resources