Can anybody explain me what is the reason for a sub class object is incapable of holding a super class constructor?
class Alpha
{
String getType1()
{
return "alpha";
}
}
class Beta extends Alpha
{
String getType1()
{
return "beta";
}
String acc()
{
return "acc";
}
}
public static void main(String[] args)
{
Alpha a1=new Beta();
System.out.println(a1.getType1());
}
Here the output is "beta"; but object a1 doesnt have the visibility to acc()?
Nothing surprising here:
System.out.println(a1.getType1());
You are calling a method that is defined in the super class; and overridden in the a subclass. You create an instance of the subclass; and the method that gets executed ... is the overridden version.
The fact that Beta contains another method which is not at all used in your example anyway doesn't come into play here at all. And even if getType1() would be calling acc() - that would still work. That is the essence of of polymorphism!
And just to be precise: none of the methods you have in your classes is a constructor!
i just found the answer here we need to know that when we create beta() internally it will call all its super class default constructors hence the JVM knows that there is more than one existing class but when i declare and initialze like:
Alpha a1=new Beta();
eventhough the JVM knows that beta class is existing but your restricting your access of a1 by saying it is of the type Alpha class hence it cannot access your subclass methods.
When you create a object of child class making reference to its parent class as you did, you only have visible to those methods which belongs to the parent class. but if you want to call the child method using reference of parent class then you have to declare the body of the method in parent class which you have in child class. then it will be visible and this concept is called method overriding.
If you don't need to create the object of your super class then you can declare class as abstract and then you can simply put that method as abstract keyword shown as below.
abstract class Alpha
{
String getType1()
{
return "alpha";
}
abstract String acc();
}
class Beta extends Alpha
{
String getType1()
{
return "beta";
}
#Overriding
String acc()
{
return "acc";
}
}
public static void main(String[] args)
{
Alpha a1=new Beta();
System.out.println(a1.getType1());
}
Child classes are privileged to access to default constructor of parent class until unless you have restricted it with private access modifier.
Your cases is an example of method overloading. Actual call to overloaded method is resolved at run time. Which method will be called, depends on the concrete object not type of object. Here your reference is of type Alpha but the object is of Type Beta. So method getType1() here will print beta which is correct behavior.
Related
This is probably answered somewhere, but I have no idea what to search for. Imagine you have the following...
The superclass, Animal.java
public class Animal {
public String noise = "squeak";
public String toString() { return noise; }
}
The subclass, Lion.java
public class Lion extends Animal {
public String noise = "ROAR!!";
public String toString() { return noise; }
}
The main class, Runner.java
public class Runner {
public static void main(String[] args) {
Animal a = new Animal();
System.out.println(a);
System.out.println(a.noise);
Lion b = new Lion();
System.out.println(b);
System.out.println(b.noise);
Animal c = new Lion();
System.out.println(c);
System.out.println(c.noise);
}
}
The output is:
squeak
squeak
ROAR!!
ROAR!!
ROAR!!
squeak
Why does c.noise return squeak? What is the difference between instance method invocation and instance variables that one returns what you'd expect, and the other does not? Why does Java do this?
Thanks
Short answer:
You can override methods, but it's not possible to override fields.
Long answer:
Each class sees the methods and fields of it's own and of it's parents (except for private methods). If the child delcares a method, whose name is the same, as the name of the method in his parent class, this method becomes overridden - if this method is somehow invoked on the child instance (even from the one of the parent's methods), the brand new method will be used instead of the parent's one. Child may still call the original method of his last parent via super.method(...) call.
But the story is different when we come to the fields. If the child declares a new field, that is named exactly as the field in parent class, it will simply hide the parent's field without overriding, just like the local variable hides global one. So the child methods will simply see the child's fields, but the parent's method will continue to see parent's field, and child's field will not be visible by any means from the parent class - that's what you've got.
Child can access the field of it's parent via ((Parent)this).field.
Longer answer:
So really the way you'd do this is define Lion thus:
public class Lion extends Animal {
public Lion() {
noise = "ROAR!!";
}
}
So now for Lion instances the noise member variable of Animal has been updated to ROAR!!
Of course you'd (almost) never actually have a public mutable member on a class like that in the wild.
You can not override fields, new declaration of noise in Lion hides parent's noise attribute. do like this:
public class Lion extends Animal {
// public String noise = "ROAR!!"; // <---- Remove this line
public Lion() {
noise = "ROAR";
}
public String toString() {
return noise;
}
}
All non-static methods in java are by default "virtual functions". Unless they're marked as final (which makes the method not overridable). Java uses a virtual method table to call the correct object's method.
This is because Java talks only about method overriding. Member variables can only be shadowed in child class. So when you say c.noise it actually refers to the string variable in parent class as the c if reference type Animal.
The topics you are interested in are Dynamic Dispatch and Virtual Method Table. Basically, by design, Java allows for methods to be overridden (assuming they are non-final) and at run time the JVM will execute the appropriate implementation. This polymorphic attribute is only afforded to methods. Good OO design would dictate the fields be encapsulated anyway.
I searched a lot. The difference between them is that override is for the instance method and hidden is for the static method. And the hidden is in fact the redefinition of the method. But I still don't get it.If redefinition means that the static method of parent still exists in the subclass, it is just we can't see it? Or why we call it hidden but not any other words? But if it exists, I can't find a way to call the method again. To be honest from a function level I can't find why they are different. Can some one explain it from a deeper level such as memory?
Static members(methods and variables) will not be present in the sub class(Child class) object which inherit them but they'll be present as a single copy in the memory.
Static members can be accessed by the class name of both Super class and sub class but they are not physically present in the object of these classes.
Where as when you inherit non-static members, Sub class object in memory will contain both inherited methods as well as the methods of its own. So when you try to write a similar method here, super class method will be overridden. On the other hand as static methods does not participate in inheritance, any similar method you write that is present in super class, new method will run every-time it is asked for. Parent class method is just hidden but not overridden!
From JLS 8.4.8.2, example 8.4.8.2-1 shows us that a hidden method binds to the type of the reference (Super), while an overriden method binds to the type of Object (Sub).
class Super {
static String greeting() { return "Goodnight"; }
String name() { return "Richard"; }
}
class Sub extends Super {
static String greeting() { return "Hello"; }
String name() { return "Dick"; }
}
class Test {
public static void main(String[] args) {
Super s = new Sub();
System.out.println(s.greeting() + ", " + s.name());
}
}
Output:
Goodnight, Dick
If you call Superclass.staticMethod() you will get the method as defined on the superclass, regardless of any hiding taking place in subclasses. On the other hand, if you call ((Superclass)subObj).instanceMethod() you'll still be calling the method as it is overridden in the subclass.
I have the following code snippet that attempts to use this and super.
class SuperClass
{
public final int x=10;
public final String s="super";
public String notOverridden()
{
return "Inside super";
}
public String overrriden()
{
return "Inside super";
}
}
final class SubClass extends SuperClass
{
private final int y=15;
private final String s="sub"; //Shadowed member.
#Override
public String overrriden()
{
return "Inside sub";
}
public void test()
{
System.out.println(super.notOverridden());
System.out.println(this.notOverridden());
System.out.println(this.overrriden());
System.out.println(super.overrriden());
System.out.println(this.s);
System.out.println(super.s);
System.out.println(this.x);
System.out.println(super.x);
System.out.println(this.y);
}
}
public final class Test
{
public static void main(String[] args)
{
SubClass subClass=new SubClass();
subClass.test();
}
}
In this simplest of Java code, the statements that redirect the output to the console inside the method test() within the class SubClass display the following output.
Inside super
Inside super
Inside sub
Inside super
sub
super
10
10
15
So, it appears that there is no difference between this and super, when they are used to access methods which are not overridden in its subclass(es) and in case of variables, when they are not shadowed in its subclass(es).
Both of them tend to point to super class members. There is however, an obvious difference, if such is not a case.
Are they same, when methods are not overridden or variables are not shadowed in respective subclasses?
So, it appears that there is no difference between this and super,
when they are used to access methods which are not overridden in
its subclass(es) and in case of variables, when they are not
shadowed in its subclass(es).
There is a difference. If you override methods in third class, and call test from it, you will see, that super still calls implementations of SuperClass. And this will call new implementations (overridden).
Addition:
this.method() usage implies the method belongs to instance of the object. So the last implementation will be used (with exception of private methods).
super.method() usage implies method of the instance, but implemented before the current class (super, or super.super etc).
Yes, they are the same. notOverridden methods and not shadowed variables are inherited by subclass.
To better understand this, knowing how object is located in memory is helpful. For example in the figure below. Assume it's an object of a subclass. The blue area is what it inherits from its parent, and the yellow area is what is defined by itself. The method has the similar design except that it uses a Vtable.
Child object has the same memory layout as parent objects, except that it needs more space to place the newly added fields. The benefit of this layout is that a pointer of parent type pointing at a subclass object still sees the parent object at the beginning.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can we override static method in Java?
We cannot override the static methods of the base class.
Actually I tried something like this:
// Base class
public class StaticExampleImpl {
protected String name="overriding";
public static void display(){
System.out.println("static method display : base class");
}
}
Then the derived class is as follows:
//derived class
public class StaticDemo extends StaticExampleImpl {
// cannot override the static methods...
//#Override
public static void display(){
System.out.println("child!!! static method display");
}
public static void main(String[] args) {
StaticDemo d=new StaticDemo();
d.display(); // derived class display is called rather than Base class.
}
}
So, when I uncomment the #Override method, it gives error as "Static methods cannot be overriden". But with commenting it works fine. So, when we create the Objects and call the static methods with the instances, those work fine. so what is the difference??
because static methods are not get inherited.
When you uncomment #Override it means you are trying to override the
static method which is not possible thats why you are getting an
error.
But when you comment //#Override it means you are declaring a new
method in child class.
Static methods does not belong to an instance of a class, it belongs to the actual class.
When you call d.display();, you are really calling the static method of the StaticDemo d reference's static method.
if you did :
StaticExampleImpl d2 = new StaticDemo();d2.display(), you will find that it calls the base class's display.
However, don't do this. It leads to confusing code, and is a bad way to implement inheritance poorly.
Overriding depends the an instance of a class. polymorphismis that you can subclass a class and the objects implementing those subclasses will have different behaviors for those method defined in the superclass (and overridden in the subclasses) .static methods does not belong to an instance of a class so the concept is not applicable.
Static methods cannot be inherited. If you want to call the 'base' class static method, you have to explicitely call StaticExampleImpl.display().
Static methods are bound to class they can't be inherited thats why you can't have base class static method in derived class.
If you are trying to override a static method, there is probably something wrong with your design.
OOP and Polymorphism allows you to do the following:
public class MyClass1 {
public String toString() { return "MyClass1 Instance"; }
}
public class MyClass2 extends MyClass1 {
#Override
public String toString() { return "MyClass1 Instance"; }
}
public void printSomething(MyClass1 myclass1){
System.out.println(myclass1);
}
Inside printSomething, the toString method which is going to be called is the one on the runtime type of myClass1: when you pass inside printSomething an instance of MyClass2, its compile-type will be MyClass1 but its runtime type will be MyClass2
It is clear that to use polymorphism you need objects instances, where the actual runtime type could different from the compile type. Static methods however do not belong to any object instance, but to the class. Why don't you explain us what you are trying to achieve?
The following code:
StaticExampleImpl one = new StaticExampleImpl();
StaticDemo two = new StaticDemo();
StaticExampleImpl three = two;
one.display();
two.display();
three.display();
Will yield the following output:
static method display : base class
child!!! static method display
static method display : base class
As you can see, the method does not get inherited. This is why they are called 'static methods': they are called statically, not dynamically, as instance methods would be. The compile-time type of the class is what matters when calling static methods, not the runtime type.
This is also why you shouldn't call static methods through object instances. Always call them like this:
StaticExampleImpl.display();
StaticDemo.display();
This completely takes away the confusion that might (will) come up when people expect inheritance to work for these methods.
any static block in java, may be static variables, methods are loaded when the class is loaded. You probably know about class loader in java. So thing is static block (methods, variables or anything is static) is loaded once. So you can’t actually override any static block.
Commenting #Override means that you are writing another static method in sub class, but not just overriding base class method.
Let's say I have a base class named Entity. In that class, I have a static method to retrieve the class name:
class Entity {
public static String getClass() {
return Entity.class.getClass();
}
}
Now I have another class extend that.
class User extends Entity {
}
I want to get the class name of User:
System.out.println(User.getClass());
My goal is to see "com.packagename.User" output to the console, but instead I'm going to end up with "com.packagename.Entity" since the Entity class is being referenced directly from the static method.
If this wasn't a static method, this could easily be solved by using the this keyword within the Entity class (i.e.: return this.class.getClass()). However, I need this method to remain static. Any suggestions on how to approach this?
Don't make the method static. The issue is that when you invoke getClass() you are calling the method in the super class - static methods are not inherited. In addition, you are basically name-shadowing Object.getClass(), which is confusing.
If you need to log the classname within the superclass, use
return this.getClass().getName();
This will return "Entity" when you have an Entity instance, "User" when you have a User instance, etc.
Not possible. Static methods are not runtime polymorphic in any way. It's absolutely impossible to distinguish these cases:
System.out.println(Entity.getClass());
System.out.println(User.getClass());
They compile to the same byte code (assuming that the method is defined in Entity).
Besides, how would you call this method in a way where it would make sense for it to be polymorphic?
This works for me
this.getClass().asSubclass(this.getClass())
But I'm not sure how it works though.
Your question is ambiguous but as far as I can tell you want to know the current class from a static method. The fact that classes inherit from each other is irrelevant but for the sake of the discussion I implemented it this way as well.
class Parent {
public static void printClass() {
System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
}
}
public class Test extends Parent {
public static void main(String[] args) {
printClass();
}
}
Create a member String variable in the superclass.
Add the this.getClass().getName() to a constructor that stores the value in the member String variable.
Create a getter to return the name.
Each time the extended class is instantiated, its name will be stored in the String and accessible with the getter.
The superclass should not even know of the existence of the subclass, much less perform operations based on the fully qualified name of the subclass. If you do need operations based on what the exact class is, and can't perform the necessary function by inheritance, you should do something along these lines:
public class MyClassUtil
{
public static String doWorkBasedOnClass(Class<?> clazz)
{
if(clazz == MyNormalClass.class)
{
// Stuff with MyNormalClass
// Will not work for subclasses of MyNormalClass
}
if(isSubclassOf(clazz, MyNormalSuperclass.class))
{
// Stuff with MyNormalSuperclass or any subclasses
}
// Similar code for interface implementations
}
private static boolean isSubclassOf(Class<?> subclass, Class<?> superclass)
{
if(subclass == superclass || superclass == Object.class) return true;
while(subclass != superclass && subclass != Object.class)
{
subclass = subclass.getSuperclass();
}
return false;
}
}
(Untested code)
This class doesn't know about its own subclasses, either, but rather uses the Class class to perform operations. Most likely, it'll still be tightly linked with implementations (generally a bad thing, or if not bad it's not especially good), but I think a structure like this is better than a superclass figuring out what all of its subclasses are.
Why do you want to implement your own getClass() method? You can just use
System.out.println(User.class);
Edit (to elaborate a bit): You want the method to be static. In that case you must call the method on the class whose class name you want, be it the sub-class or the super-class. Then instead of calling MyClass.getClass(), you can just call MyClass.class or MyClass.class.getName().
Also, you are creating a static method with the same signature as the Object.getClass() instance method, which won't compile.
A static method is associated with a class, not with a specific object.
Consider how this would work if there were multiple subclasses -- e.g., Administrator is also an Entity. How would your static Entity method, associated only with the Entity class, know which subclass you wanted?
You could:
Use the existing getClass() method.
Pass an argument to your static getClass() method, and call an instance method on that object.
Make your method non-static, and rename it.
If I understand your question correctly, I think the only way you can achieve what you want is to re-implement the static method in each subclass, for example:
class Entity {
public static String getMyClass() {
return Entity.class.getName();
}
}
class Derived extends Entity {
public static String getMyClass() {
return Derived.class.getName();
}
}
This will print package.Entity and package.Derived as you require. Messy but hey, if those are your constraints...
If i am taking it right you want to use your sub class in base class in static method
I think you can do this by passing a class parameter to the method
class Entity {
public static void useClass(Class c) {
System.out.println(c);
// to do code here
}
}
class User extends Entity {
}
class main{
public static void main(String[] args){
Entity.useClass(Entity.class);
}
}
My context: superclass Entity with subclasses for XML objects.
My solution:
Create a class variable in the superclass
Class<?> claz;
Then in the subclass I would set the variable of the superclass in the constructor
public class SubClass {
public SubClass() {
claz = this.getClass();
}
}
it is very simple done by
User.getClass().getSuperclass()