Instantiate Subclasses from Static Methods - java

I'm think perhaps there is not a way to do this, but I thought it worth asking. I want to do something like the following:
public class Super {
public static String print() { System.out.println(new Super().getClass().getSimpleName()); }
public Super() {}
}
public class Subclass extends Super {
public Subclass() {}
public void main(String[] args) {
Super.print();
Subclass.print();
}
}
My hope is to get the Super.print() to show "Super" and Subclass.print() to show "Subclass". I don't see how to do this from a static context however. Thanks for the help.
I'm well aware that I can do this without static methods, and that I can pass a class into each method call. I don't want to do that as that requires redefining several static methods on many subclasses.

You can simply define a separate Subclass.print() method with the desired implementation. Static methods are class scoped, so every subclass can have its own implementation.
public class Subclass {
public Subclass() {}
public static String print() {
System.out.println(Subclass.class.getSimpleName());
}
public void main(String[] args) {
Super.print();
Subclass.print();
}
}
Note that your code can be somewhat simplified - Super.class suffices instead of new Super().getClass().
Also note, that static methods are not polymorphic - Super.print() and Subclass.print() will always call the method in the respective class. This is why they are bound to a class, not an object.
If you have a large class hierarchy, you may end up with a lot of duplicated code by implementing a separate static print() in each. Instead, you could define a single non-static method to do the job:
public abstract class Super {
public final String print() {
System.out.println(this.getClass().getSimpleName());
}
...
}
Note that this method does not even need to be polymorphic - this.getClass() will always return the actual subclass token.
Note also that I declared Super as abstract - this is (almost always) good practice to follow with base classes.

You can do this with out using static methods
public class Parent {
public print(){
System.err.println(this.getSimpleName());
}
}
public class Child extends Parent {
public void main(String[] args) {
Parent p = new Parent();
p.print();
Child c = new Child();
c.print();
}
}

Related

Calling a method of abstract class from a concrete class without extending

Example abstract class is bellow.
public abstract class Vehicle {
void maintain(String str) {
System.out.println(str);
}
}
Example concrete class is bellow.
public class Driver {
public static void main(String[] args) {
}
}
Now I need to access the maintain method without extending the Vehicle class.Is there any way to do this without using static content?
No, there isn't, because maintain is an instance method. To call an instance method, you must have an instance. You can't create an instance of an abstract class.
You can subclass it anonymously (see this tutorial), but you still need to subclass it.
You can use an anonymous inner class. I've used your example code but also defined an anstract method in Vehicle
public class AbstractTest {
public static void main(String[] args){
Vehicle v = new Vehicle() {
#Override
void myOtherAbstractMethod() {
// Do what you need here
}
};
v.maintain("foo");
}
public static abstract class Vehicle {
void maintain(String str) {
System.out.println(str);
}
abstract void myOtherAbstractMethod();
}
}
You cannot do that as abstract classes are abstract. Also in your case there's no connection between Driver and Vehicle so even if you would be able to compile that code (you won't), then ClassCastException would show up.
You must extend abstract class first, like it or not.

How to force my subclass constructor not to call base class constructor?

public class Base {
public Base() {
foo();
}
public void foo() {
System.out.println("Base.foo()");
}
}
public class Derived extends Base {
public Derived () {}
public void foo() {
System.out.println("Derived.foo()");
}
}
And then, when i call those:
public class Running {
public static void main(String[] args) {
Base b = new Base();
Derived d = new Derived();
}
}
It outputs:
*Base.foo()*
*Derived.foo()*
So why, when it gets to derived constructor, it invokes the base constructor but uses the derived's method instead?
PS: If I mark those methods as private, it will print out:
*Base.foo()*
*Base.foo()*
This is how Java works read this page https://docs.oracle.com/javase/tutorial/java/IandI/super.html
And more specifically the Note here :
Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the
no-argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem.
So as you can see this is expected behavior. Even though you dot have a super call it is still automatically inserting it.
In regards of the second Question even though you are within the super constructor body still you Instance is of the Subtype. Also if you have some familiarity with C++ read this Can you write virtual functions / methods in Java?
The reason why it will write the base class when marking with private is because private methods are not Inherited. This is part of the Inheritance in Java topic.
To answer the question in your title. As I said, you cannot avoid the base class constructor being called (or one of the base class constructors if it has more than one). You can of course easily avoid the body of the constructor being executed. For example like this:
public class Base {
public Base(boolean executeConstructorBody) {
if (executeConstructorBody) {
foo();
}
}
public void foo() {
System.out.println("Base.foo()");
}
}
public class Derived extends Base {
public Derived() {
super(false);
}
public void foo() {
System.out.println("Derived.foo()");
}
}
public class Running {
public static void main(String[] args) {
Base b = new Base(true);
Derived d = new Derived();
}
}
Now the main method prints only:
Base.foo()
Because in the contructor of the Derived class it automatically gets injected a call to super(), if you do not add a call to super or to other constructor in the same class (using this).

Can a private method in super class be overridden in the sub-class?

Can private methods be overridden in Java?
If no, then how does the following code work?
class Base{
private void func(){
System.out.println("In Base Class func method !!");
};
}
class Derived extends Base{
public void func(){ // Is this a Method Overriding..????
System.out.println("In Derived Class func method");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func();
}
}
No, you are not overriding it. You can check by trying to mark it with #Override, or by trying to make a call to super.func();. Both won't work; they throw compiler errors.
Furthermore, check this out:
class Base {
private void func(){
System.out.println("In base func method");
};
public void func2() {
System.out.println("func2");
func();
}
}
class Derived extends Base {
public void func(){ // Is this an overriding method?
System.out.println("In Derived Class func method");
}
}
class InheritDemo {
public static void main(String [] args) {
Derived D = new Derived();
D.func2();
}
}
It will print:
func2
In base func method
When you change func() in Base to public, then it will be an override, and the output will change to:
func2
In Derived Class func method
No, a private method cannot be overridden because the subclass doesn't inherit its parent's private members. You have declared a new method for your subclass that has no relation to the superclass method. One way to look at it is to ask yourself whether it would be legal to write super.func() in the Derived class. There is no way an overriding method would be banned from accessing the method it is overriding, but this would precisely be the case here.
No, it is not. You can mark an override just to make sure like this:
#Override
public void func(){
System.out.println("In Derived Class func method");
}
And in this case it would be a compiler error.
You are not overriding. You cannot override private members, you are merely defining a new method in Derived. Derived has no knowledge Base's implementation of func() since its declared as private. You won't get a compiler error when you define func() in Derived but that is because Derived does not know Base has an implementation of func(). To be clear: it would be incorrect to say you are overriding Base's implementation of func().
In addition to the already correct answer, consider this:
public class Private {
static class A {
public void doStuff() {
System.out.println(getStuff());
}
private String getStuff() {
return "A";
}
}
static class B extends A {
public String getStuff() {
return "B";
}
}
public static void main(String[] args) {
A a = new A();
a.doStuff();
a = new B();
a.doStuff();
B b = new B();
b.doStuff();
}
}
This will print
A
A
A
although B "overrides" getStuff(). As implementation of doStuff() is fixed to calling A#getStuff(), no polymorphism will be triggered.
Nope because if you do something like Base b = new Derived(); you still won't be able to call b.func(). What you're doing is called "hiding".
Since the method is private it is not visible to the other classes.Hence the derived class does not inherit this method.
So this is not the case of overriding
Method hiding will be happening here instead of overriding. like what happens in case of static.
Actually,you are not overriding.Before Java5
an overridden method's return type must match with parent class's method.
But Java 5 introduced a new facility called covariant return type.You can override a method with the same signature but returns a subclass of the object returned. In another words, a method in a subclass can return an object whose type is a subclass of the type returned by the method with the same signature in the superclass.
you can follow this thread :Can overridden methods differ in return type?
The private member of the base class cannot be access by anyone outside of the class and cannot be overridden. The function in the derive class is an independent function that can be access by anywhere.
The code would run the function in the derived class
A private method can never be over ridden. It is always hidden.
In your example - Derived class has one parent class private method and has its own function func. Both are different, and the func is not over ridden. Its a separate independent function.
If you create a new function in parent class calling parent class function, the parent func will be called, if parent class reference is used as opposed in the case of method over ridding
Note : An object defines the members which it has, and a reference defines which it can access
// Method Over ridding case
class Base{
public void func(){
System.out.println("Parent class");
};
public void func1(){
func();
}
}
class Derived extends Base{
public void func(){
System.out.println("Derived class");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func1(); // Prints Derived class
Base b = new Derived();
b.func1(); // Prints Derived class - no matter parent reference is calling,as there as method is overridden - Check func1() is in parent class, but id doesn't call parent class func() as the compiler finds a func() method over ridden in derived class
}
}
// Method Hidding case - Private and static methods case
class Base{
private void func(){
System.out.println("Parent class");
};
public void func1(){
func()
}
}
class Derived extends Base{
public void func(){ // Is this a Method Overriding..????
System.out.println("Derived class");
}
}
class InheritDemo{
public static void main(String [] args){
Derived d = new Derived();
d.func1(); // Prints Derived class
Base b = new Derived();
b.func1();
// Prints Parent class - the reason is we are using the parent class reference, so compiler is looking for func() and it founds that there is one private class method which is available and is not over ridden, so it will call it. Caution - this won't happen if called using derived class reference.
b.func();
// this prints the Derived class - the compiler is looking func(), as Derived class has only one func() that it is implementing, so it will call that function.
}
}
Read comments in the below code snippet to find the answer.
Sources:
Definition reference:
Credits for the source code example(reference) from the book - "OCA Oracle Certified Associate Java SE 8 Programmer Study Guide Exam 1Z0-808 Book" from 'Jeanne Boyarsky' and 'Scott Selikoff'.
public class Deer {
public Deer() { System.out.print("Deer"); }
public Deer(int age) { System.out.print("DeerAge"); }
private boolean hasHorns() { return false; }
public static void main(String[] args) {
Deer deer = new Reindeer(5);
System.out.println(","+deer.hasHorns());// false is printed.
}
}
class Reindeer extends Deer {
public Reindeer(int age) { System.out.print("Reindeer"); }
private boolean hasHorns() { return true; } // Overriding possible, but is of no use in the below context.
// Below code is added by me for illustration purpose
public static void main(String[] args) {
Deer deer = new Reindeer(5);
//Below line gives compilation error.
//System.out.println(","+deer.hasHorns());
}
}

Static method override

class XYZ{
public static void show(){
System.out.println("inside XYZ");
}
}
public class StaticTest extends XYZ {
public static void show() {
System.out.println("inside statictest");
}
public static void main(String args[]){
StaticTest st =new StaticTest();
StaticTest.show();
}
}
though we know static methods cant be overridden. Then what actually is happening?
Static methods belong to the class. They can't be overridden. However, if a method of the same signature as a parent class static method is defined in a child class, it hides the parent class method. StaticTest.show() is hiding the XYZ.show() method and so StaticTest.show() is the method that gets executed in the main method in the code.
Its not overriding they are two different method in two different class with same signature. but method from XYZ isn't available in child class through inheritance .
It will call method from StaticTest
It's not overriden properly said... Static methods are 'tied' to the class so
StaticTest.show();
and
XYZ.show();
are two totally different things. Note you can't invoke super.show()
To see the difference you have to use more powerful example:
class Super {
public static void hidden(Super superObject) {
System.out.println("Super-hidden");
superObject.overriden();
}
public void overriden() {
System.out.println("Super-overriden");
}
}
class Sub extends Super {
public static void hidden(Super superObject) {
System.out.println("Sub-hidden");
superObject.overriden();
}
public void overriden() {
System.out.println("Sub-overriden");
}
}
public class Test {
public static void main(String[] args) {
Super superObject = new Sub();
superObject.hidden(superObject);
}
}
As Samit G. already have written static methods with same signature in both base and derived classes hide the implementation and this is no-overriding. You can play a bit with the example by changing the one or the another of the static methods to non-static or changing them both to non-static to see what are the compile-errors which the java compiler rises.
It's not an override, but a separate method that hides the method in XYZ.
So as I know, any static member (method or state) is an attribute of a class, and would not be associated with any instance of a class. So in your example, XYZ is a class, and so is StaticTest (as you know). So by calling the constructor two things first happen. An Object of type Class is created. It has a member on it call showed(). Class, XYZ.class, extends from Object so has all those Object methods on it plus show(). Same with the StaticClass, the class object has show() on it as well. They both extend java.lang.Object though. An instance of StaticClass would also be an instance of XYZ. However now the more interesting question would be what happens when you call show() on st?
StaticClass st = new StaticClass();
st.show();
XYZ xyz = st;
xyz.show();
What happens there? My guess is that it is StaticClass.show() the first time and XYZ.show() the second.
Static methods are tied to classes and not instances (objects).
Hence the invocations are always ClassName.staticMethod();
When such a case of same static method in a subclass appears, its called as refining (redefining) the static method and not overriding.
// Java allows a static method to be called from an Instance/Object reference
// which is not the case in other pure OOP languages like C# Dot net.
// which causes this confusion.
// Technically, A static method is always tied to a Class and not instance.
// In other words, the binding is at compile-time for static functions. - Early Binding
//
// eg.
class BaseClass
{
public static void f1()
{
System.out.println("BaseClass::f1()...");
} // End of f1().
}
public class SubClass extends BaseClass
{
public static void f1()
{
System.out.println("SubClass::f1()...");
// super.f1(); // non-static variable super cannot be referenced from a static context
} // End of f1().
public static void main(String[] args)
{
f1();
SubClass obj1 = new SubClass();
obj1.f1();
BaseClass b1 = obj1;
b1.f1();
} // End of main().
} // End of class.
// Output:
// SubClass::f1()...
// SubClass::f1()...
// BaseClass::f1()...
//
//
// So even though in this case, called with an instance b1 which is actually referring to
// an object of type SuperClass, it calls the BaseClass:f1 method.
//

What to do with static method overrides?

For example,
public class A {
public static int f() { return 1; }
}
public class B extends A {
public static long f() { return 100L; }
}
Unfortunately B.f() couldn't be compiled because B.f() tries to override A.f(), and so the name clashes because the return types aren't compatible.
I'm weired what's purpose to override a static method? Any use case? Can I just hide away A.f() in class B?
Actual usage:
class EntityDTO {
public static List<EntityDTO> marshal(Collection<? extends Entity> entities) {
...
}
}
class BookDTO extends EntityDTO {
public static List<BookDTO> marshal(Collection<? extends Book> books) {
...
}
}
Strictly speaking, static methods can not be overridden. Method overriding is exclusively a feature of object polymorphism, and static methods doesn't belong to any object but the class itself.
Having clarified that, you should not make any of your methods static. That would solve your problem in hand, at least. As the method arguments are different, it will not be considered as overriding, but overloading.
static methods are not overriden...But it is called method hiding. The benefits of using the same method name and parameters are just like any other method overriding benefits
static method can not be overridden.
Notice: your B.f() should return int rather than long to pass compile.
I can't think of a use case where overriding static functions (in Java) can be useful, but if you ever absolutely must achieve it, here's how:
import java.lang.reflect.Method;
class A {
public static void callOut() {
System.out.println("A.callOut");
}
}
public class B extends A {
public static void callOut() {
System.out.println("B.callOut");
}
public static void main(String[] args) throws Exception
{
A a = new A();
A b = new B();
Method aM = a.getClass().getMethod("callOut");
Method bM = b.getClass().getMethod("callOut");
aM.invoke(null); // prints A.callOut
bM.invoke(null); // prints B.callOut
}
}
Maybe you need to rethink you design, if you have a need to override the marshal method, then it shouldn't be static in the first place.

Categories

Resources