inheritance in java does not work the way I expected - java

I have the following class:
public class X {
public void A() {
B();
}
private static void B() {
System.out.println("111111111");
}
}
Now I have the following inherited class Z:
public class Z extends X {
private static void B() {
System.out.println("22222222");
}
}
now if I do
Z myClass = new Z();
Z.A();
I will get: 111111111 as a result. (Also, eclipse tells me that B() in the inherited class is never called).
Why? And how can I run the inherited B method?

The B methods are static. When you call the method A it uses the implementation of class B (because that's where the method A is defined). Class B is not aware of the existence of class Z and cannot call a method of class Z.
Because the method is static, it's not overridden upon inheriting from B. Polymorphism only works with instances of a class. Static method does not play the polymorphism game and cannot be overridden.

Change access modifier of method from private static to protected
If you re-define base class non-static & non-private method in derived class, it's called overriding.
If you re-define base class static method in derived class, it's called method hiding or method shadowing.
You have done hiding rather overriding in your example.
Have a look at this SE Question

You're calling X's inherited A method, and this calls its private B method.
private methods and attributes are not inherited.

It looks like you are overriding method B() in class Z but method B() is not overridden here. Since B() is static so class A and class Z has there own method B(). Scope of all the Static methods and variables are class level not an object level.

Related

Why is this code calling a private method? [duplicate]

public class Shape
{
final private void print()
{
System.out.println("in class Shape");
}
public static void main(String[] args)
{
Shape shape=new Rectangle();
shape.print();
//calling shape class function
//giving output in class shape
}
}
public class Rectangle extends Shape
{
public void print()
{
System.out.println("in class Rectangle");
//super.print();
}
}
Ques: why private function don't show polymorphic behaviour ?
and we are still overriding final method?
its calling base class funtion why?
A Private function is not visible nor callable from its children; hence these are two completely different functions. There is nothing to overwrite from the perspective of the child class, because it is not aware that the parent even has a print() function.
Making it final private void print() is to prevent it from overriding in sub-classes.
As final prevents overriding and private makes the method invisible to the sub-classes so that it cant be accessed
See also :
Java `final` method: what does it promise?
Overriding private methods in Java
You are not actually over-ridden the print method because of private. They are completely different.
More over you cannot override a final method.
This is the place where #override annotation helps you better. If you try to place the annotation, then you realize the behaviour at compile time itself.
In addition to Eriks answer from the Java Language Specification:
A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:
m is a member of the direct superclass of C.
m is public, protected, or declared with package access in the same package as C.
No method declared in C has a signature that is a subsignature (§8.4.2) of the signature of m.
and
An instance method mC declared in or inherited by class C, overrides from C another method mA declared in class A, iff all of the following are true:
[...]
One of the following is true:
mA is public.
mA is protected.
So your subclass doesn't inherit the private methods, hence there is nothing to override.
Polymorphism is the capability of an action or method to do different
things based on the object that it is acting upon. In other words,
polymorphism allows you define one interface and have multiple
implementation. This is one of the basic principles of object oriented
programming.
The method overriding is an example of runtime polymorphism. You
can have a method in subclass overrides the method in its super
classes with the same name and signature. Java virtual machine determines the proper
method to call at the runtime, not at the compile time.
But if you will think as print() is instance method and at runtime why it is not calling from Rectangle print() method.
The reason is as print() of subclass is not a overriden method as parent class method is final which cannot be overriden.
Shape shape=new Rectangle();
shape.print(); // prints in the shape class
((Rectangle)shape).print(); //prints in the rectangle class
As parent's class method is private so it is not visible for outside world and as it is final it cannot be overriden.
In your example it is shown as private final method so this method is not visible out side the class. So Rectangle can't see the method defined inside Shape class.
public class A{
final private method1(){
}
final public method2(){
}
public method3(){
}
}
public class B extends A{
public method1(){
//it is legal. but it is not a override. this method can't see the method1 defined in A
}
public method2(){
//throw error. because final method can't be overriden
}
public method3(){
//legal override method
}
}

Subclass Reference by Superclass variable?

When a class extends a class, we can use Super-class reference while assigning memory to the subclass object.
I have understood so far is that it is ok to do so, because a subclass inherits the data of its parent class, but it cannot access the members of the subclass because it is the just the reference, and hence does not know of what additions are done by the child class.
My question is when I included method hiding to the above concept, the superclass reference variable started to refer to the child's class function. Why is that ? Why it didnt call it's own method as it is supposed to ?
class A{
void show(){ System.out.print("CLass A. \n"); }
}
class B extends A{
void show(){System.out.print("Class B. \n"); }
}
class Main{
public static void main(String[] args){
A a= new A();
B b= new B();
a.show(); // prints Class A
b.show(); // prints Class B
A a1= new B();
a1.show(); // print Class B. why is this ? it should be Class A as per theory?
}
}
variables and methods are two different things. Variables stick to their types where as methods get executed run time based on the implementation type provided.
Polymorphism. Methods bind dynamically and choosen at run time. If you ovveride them implementation class, they get executed otherwise the implementation from type class gets execute.
When you write
A a1= new B();
Means that please call the implementations from the class B(which is on right side) which are from type A
You have to know about overriding concept in java.
From oracle documentation page regarding overriding:
Overriding and Hiding Methods
Instance Methods
An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed.
But overriding is different from hiding.
Static Methods
If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.
The distinction between hiding a static method and overriding an instance method has important implications:
The version of the overridden instance method that gets invoked is the one in the subclass.
The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
Example to understand:
public class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal");
}
}
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public void testInstanceMethod() {
System.out.println("The instance method in Cat");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
Animal.testClassMethod();
myAnimal.testInstanceMethod();
}
}
output:
The static method in Animal
The instance method in Cat
It allways calls the method from the most specific class.

Calling of Constructors in a Java

In the book Java: The complete reference
// Demonstrate when constructors are called.
// Create a super class.
class A {
A() {
System.out.println("Inside A's constructor.");
}
}
// Create a subclass by extending class A.
class B extends A {
B() {
System.out.println("Inside B's constructor.");
}
}
// Create another subclass by extending B.
class C extends B {
C() {
System.out.println("Inside C's constructor.");
}
}
class CallingCons {
public static void main(String args[]) {
C c = new C();
}
}
Output:
Inside A’s constructor
Inside B’s constructor
Inside C’s constructor
It is demonstrating how the constructor of a subclass is called. But why are constructors of the super class called in the absence of a super() constructor.
Why did the Java Language designers consider it necessary to do so?
As others have pointed out, if you don't start your constructor with a super(...) call, the compiler will put in a call to super() for you.
As to the why, you have to start with remembering what a constructor is for in the first place: initializing the object. What does that mean, specifically? In practice, it means assigning values to the object's fields, and establishing invariants.
Without a call to super(), the B and A classes wouldn't have a chance to do that for whatever fields they contain. And you can't even have the C() constructor do it for them, if those fields are private, since private fields aren't accessible outside your class (not even your super class's fields are accessible). Even if you could, it wouldn't be a good idea; it would also break encapsulation. For instance, imagine having to change your code if a super class -- possibly a complex one whose internals you're not an expert in -- suddenly decided to change its implementation details.
To illustrate this, consider a very simple set of classes:
public class Super {
private final String name;
Super() {
name = "default";
}
public String name() {
return name.toUpperCase();
}
}
public class Sub extends Super {
public Sub() {
// don't do anything
}
}
When you instantiate Sub, it will start out by calling Super's constructor. If it didn't, the name field would be null (the default value for reference types). But the name() method doesn't check for null; it assumes that the reference is non-null, because the constructor establishes that invariant. So, in our pseudo-Java that doesn't call the super constructor, Super.name has to get a bit more complicated -- it has to check for name == null.
You can imagine that as the classes gain more fields, with more interesting invariants, this toy example can become more and more complicated. Forcing you to call the super constructor -- either explicitly or implicitly -- lets the authors of that super class establish their invariants, resulting in simpler, more maintainable code.
Every constructor calls its superclass constructor. super() call take place as the first line in the constructor. From javadoc:
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.
more here
Because it says so in the Java Language Specification.
If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.
Even it has a role with Abstract classes also. we can't initialize object of abstract class. But Child class of Abstract class calls the super() method by default. So abstract class constructor can initialize its instance variables.
for example:
public abstract class TestA {
private int a;
public TestA()
{
a=10;
}
public int displayA()
{
return a;
}
abstract void display();
}
public class TestB extends TestA{
#Override
void display() {
System.out.println("this is class B");
}
}
package Abstract;
public class TestMain {
public static void main(String[] args) {
TestA obj= new TestB();
System.out.println(obj.displayA());
}
}
Output is : 10
Here you can see, when we initiating object of class TestB , by default super constructor is calling and TestA's constructor is assigning the value of a. If super will not be called by default we can't assign instance variables of abstract class.
Inheritance is basically inheriting all the properties of your parent class. So if a sub class constructor is called, it should definitely and by default inherit all its parent class properties also. In the following code, all the properties of class A should be made available in class B also, so if I just call B's constructor, all the class A's properties(except private) are also initialized and made available, meaning B has inherited A's properties
class A {
protected int a;
A() {
a=12;
System.out.println("Inside A's constructor.");
}
}
class B extends A {
B() {
System.out.println("Inside B's constructor.");
System.out.println(a);
}
}
public class ConstructorInheritance {
public static void main(String args[]) {
B b=new B();
}
}
output:
Inside A's constructor.
Inside B's constructor.
12
Imagine class C accessing an unitialized variable of class B or A. Implicitly calling constructors of class B-->class A makes sure that you are always accessing initialized variables of inherited classes(A or B)
"The Java programming language" says "A constructor in subclass can initialize its individual state, however, as keeping contract, only super class knows how to initialize super class's state".
Thus, constructor of super class have to be called. There is sequence how the constructor processed:
Call super class constructor
Initialize fields with initializers and initialization blocks
Execute body of the constructor
For more details, have a look of the book to section "3.2".

Field inheritance on Java

Are fields only inherited "one level up"?
By that I mean that if I have a Superclass to a Class, which then has a Subclass, and the Superclass has a field, the Class will inherit it and the Subclass won't. Is this correct?
And if it is, is there a way to make the Subclass automatically inherit the field from the Superclass given that, as I understand it, there's no way to inherit from two classes at once?
Thank you to anyone who takes the time to answer. I realize my question may be impractical and in reality you'd probably just override the field or something, but I'm not trying to do anything specific, just trying to learn how Java works. Thank you.
Here's my code:
public class SuperClass {
protected int entero;
protected void method(){
entero=1;
}
public class SubClass extends Class {
public SubClass(){}
}
public class Class extends SuperClass {
public Class(){}
}
public static void main(String[] args){
Class object= new Class();
SubClass subobject= new SubClass();
/*This is where I get an error, why?*/
subobject.entero=2;
/*This one is fine*/
object.entero=2;
object.method();
System.out.println(object.entero);
}
Any class B than extends a class A, will inherit A's fields. If a class C extends B, C will inherit all non-private instance fields and methods from A and B, ie transitivity holds.
If a field is private, then one cannot directly change it from a subclass; however, you can get around this by using setter/getter methods.
If a field is protected, then a subclass has direct access to it.
EDIT 1:
In a comment you say that the field is protected, but you still can't access it from a subclass. The only thing I can think of is that you have a situation like this:
class A
{
protected int x;
}
class B extends A
{
private int x;
}
class C extends B
{
private int z = x;
}
This would NOT work because by declaring x again in B, you are hiding the x field from A. So, now C sees x as B's private variable x, which you do not have access to.
EDIT 2:
I'm not going to remove the above edit, because it's informative, but now that you posted your code, it's because your SubClass does not actually extend anything (this was later fixed in an edit).
Inheritance in Java is transitive.
If your classes are Superclass < Class < Subclass, then Subclass inherits all the non-private instance fields and methods provided by Superclass not overridden or hidden by Class or Subclass.
One level of inheritance is specified by the Java Language Specification, section 8.4.8: Inheritance, Overriding and Hiding:
A class C inherits from its direct superclass and direct superinterfaces all abstract
and non-abstract methods of the superclass and superinterfaces that are public,
protected, or declared with default access in the same package as C, and are neither
overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.
If you have classes that are:
public class SuperClass {
public void methodName() {}
//SuperClass's stuff
}
public class MidClass extends SuperClass {
//MidClass's stuff
}
public class SubClass extends MidClass {
//SubClass's Stuff
}
Then it is perfectly valid to have in your main method:
SubClass sc = new SubClass();
sc.methodName();

Is this an Instantiation of Abstract Class?

If Abstract class cannot be instantiated, then how can the variables
access and methods access of the abstract class A even without
extending is achieved in the class check (as you can see in the below
code)
Is the created a an object of abstract class A?
CODE
abstract class A
{
int a=10;
public A()
{
System.out.println("CONSTRUCTOR ONE");
}
public A(String value)
{
System.out.println("CONSTRUCTOR "+value);
}
void add(int sum)
{
System.out.println("THE SUM IS:"+sum);
}
int sub(int a,int b )
{
return(a-b);
}
}
public class check
{
public check()
{
new A("TWO"){};
}
public static void main(String args[])
{
int a,b,sum;
a=10;
b=15;
sum=a+b;
A s = new A() {};
new check();
s.add(sum);
int subb=s.sub(35,55);
System.out.println("THE SUB IS:"+subb);
System.out.println("THE VALUE OF A IS:"+s.a);
}
}
OUTPUT
CONSTRUCTOR ONE
CONSTRUCTOR TWO
THE SUM IS:25
THE SUB IS:-20
THE VALUE OF A IS:10
BUILD SUCCESSFUL (total time: 0 seconds)
The new A() {} call creates an anonymous subclass and instantiates that. Since A does not contain any abstract methods, this works.
You are creating subclass of A with this code -
A s = new A() {};
and here as well -
public check()
{
new A("TWO"){};
}
Whereas, the normal syntax for instantiation is this -
A a = new A();
which would give compilation error if you try to run this code. As such, you don't have any abstract method in your class, and hence a nominal subclass suffices and you get your code executed.
HTH,
- Manish
The normal use case is, you'd write new MyAbstractClass(){ and then implement whatever abstract methods you need to implement (and/or override existing non-abstract methods), and the compiler will infer a non-abstract subclass for you. Since your class doesn't have any abstract methods, it's not necessary to override anything.
A is marked abstract but has no abstract methods so when you do new A() {} you are providing an implementation that has nothing in it thus you are providing a concrete implementation and the class is complete.
Disregarding "visibility" (public, private, package scope, etc)... you generally need a class instance to access class members.
An exception is static classes.
Otherwise, if you have an abstract base class, you'll need to subclass to get an instance.
In your case, however, the class isn't really "abstract" (despite your attempting to label it as such). Simply because there are no abstract members or methods.
You created abstract class A without any abstract method.
Abstract classes cannot be instantiated, but they can be subclassed.
An abstract method is a method that is declared without an implementation.
In the constructor check() you just created anonymous class and call constructor A(String value).
new A("TWO"){};
This is a anonymous subclass .
1. This class create and instantiate at the same time...
2. No name of that class..
3. Because there is no name so it must need a parent .
You can get name by s.getClass().getName(); which return A$1....
A s = new A() {};
on the right side there is a new anonimus class which is inherited from A.A class haven't abstract methods so in your new anonimus class you don't need to override any methods.

Categories