Understanding the concept of inheritance in Java - java

I am just refreshing the oops features of the java. So, I have a little confusion regarding inheritance concept. For that I have a following sample code :
class Super{
int index = 5;
public void printVal(){
System.out.println("Super");
}
}
class Sub extends Super{
int index = 2;
public void printVal(){
System.out.println("Sub");
}
}
public class Runner {
public static void main(String args[]){
Super sup = new Sub();
System.out.println(sup.index+",");
sup.printVal();
}
}
Now above code is giving me output as : 5,Sub.
Here, we are overriding printVal() method, so that is understandable that it is accessing child class method only.
But I could not understand why it's accessing the value of x from Super class...
Thanks in advance....

This is called instance variable hiding - link. Basically you have two separate variables and since the type of the reference is Super it will use the index variable from Super.

Objects have types, and variables have types. Because you put:
Super sup = new Sub();
Now you have a variable sup of type Super which refers to an object of type Sub.
When you call a method on an object, the method that runs is chosen based on the type of the object, which is why it prints "Sub" instead of "Super".
When you access a field in an object, the field is chosen based on the type of the variable, which is why you get 5.

index is simply a field belonging to the parent class. Because it belongs to the parent class, it means that it's an attribute to all the children.
To simply the concept:
A Class Animal could have a field age and a field name
All sub classes would share those attributes, but would have additional field(s), which would be contained into those children classes only. For example hairColour could be the only attribute of the Dog class, but not to the class Snake, which could have a simple unique attribute venomous
In this structure all Animal have a name, and an age, which is what could define Animals in general, an each specie have some extra attribute(s) unique to them, which are contained into their respective sub classes.
Your code doesn't clearly show this, as your sub class has no constructor, indeed no super constructor call. As explained by Petar, your none private attribute index is access from the super class

This happens coz functions follows runtime binding whereas variables are bound at compile time.
So the variables depend on the reference's datatype whereas the functions depend on the value represent by the reference's datatype.

When we assigning the object of sub class to parent class object only the common property both class can be accepted by the parent class object , is called as object slicing
that's why the value of patent class 5 is printed its only happen with property not a method

Related

why subclass reference can't hold superclass object in java

class One{
}
class Two extends One{
}
class Main{
public static void main(String[] args){
Two t = new One(); // invalid
}`
}
I am not able to understand the reason behind it, why child class reference could not hold the object of parent, while superclass reference can hold the object of subclass.
Because a dog has all the behaviours of an animal, but something that is only known to be an animal is not guaranteed to have all the behaviours of a dog.
Every Child is a Parent but not every Parent is a Child. Rule of Inheritance.
If we think in terms of set theory, compared to the parent class, the child class is a super set.
The child class has all possible properties and methods, compared to the parent class.
So, a parent class object can refer to its child class object, as the child class object includes the parent's methods and properties.
Thinking vice versa, since a parent class object does not have all the methods and properties needed by a child class, a child class object cannot refer to a parent class object.
The type of TWO cannot be an instance of ONE because there are members and methods that TWO has which ONE doesn't have. However, The type of ONE can reference TWO because TWO has everything that ONE has.
For example, if ONE can WALK and TWO can also RUN, then if you have an object from the type ONE then is needs to be able to WALK. So if ONE references TWO that works because TWO can walk.
But when you have an object of type TWO then it needs to be able to RUN so you cannot reference it to ONE which cannot RUN.
Consider class Two contain a method, let say demo().
class One{
}
class Two extends One {
void demo(){
System.out.println("in Two");
}
}
class Main{
public static void main(String[] args){
Two t = new One(); // Suppose this is valid at compilation time
t.demo();
}
}
Now suppose if compiler doesn't give us error when we create object of class One i.e. child reference holds object of parent. Further t is reference of class Two, hence t.demo() is valid.
Now when program runs, reference t contains object of class One. When program reaches t.demo() then t contains object of class One and class One does not have any method named demo().
So to prevent such type of errors compiler checks if object is type of reference i.e. object class is same as reference class or child of reference class.

Why exactly does the no-arg constructor of parent class get invoked while creating an instance of child class? [duplicate]

I have a question about inheritance in Java.
I have two classes A and B , and class B, inherits from A:
public class A {
public A() {
System.out.println("Hi!");
}
}
public class B extends A {
public B() {
System.out.println("Bye!");
}
public static void main(String[] args) {
B b = new B();
}
}
When I run program B, the output is:
Hi!
Bye!
Question : why the constructor of class A is invoked, when I create and object of class B ?
I know that B inherits everything from A - all instance or class variables, and all methods, and in this sense an object of B has all characteristics of A plus some other characteristics defined in B. However, I didn't know and didn't imagine that when I create an object of type B, the constructor of A is also invoked.
So, writing this:
B b = new B();
creates Two objects - one of type B, and one of type A.
This is getting interesting,
can somebody explain why exactly this happens?
It doesn't create two objects, only one: B.
When inheriting from another class, you must call super() in your constructor. If you don't, the compiler will insert that call for you as you can plainly see.
The superclass constructors are called because otherwise the object would be left in an uninitialized state, possibly unbeknownst to the developer of the subclass.
Your subclass actually looks like this after the compiler inserts the super call:
public class B extends A {
public B() {
super();
System.out.println("Bye!");
}
}
It doesn't create 2 objects, it only creates one instance of B. The reason the super class constructor is invoked is because, like you said, B has all of the fields of A, and these fields need to be initialized.
Remember inheritance is an "is a" relationship between the base class and the subclass, thus every time you have an instance of a subclass, by definition you will also have an instance of the base class (as part of the instance, not as two separate instances). To initialize the base class properly the constructor is called.
Additionally, think about what would happen if you subclass depended on some internal state of the base class. Wouldn't you want the instance of the base class to be initialized then?
This is done because the constructor is used to initialize the object. Since B is also an A, it calls the constructor for A first, then the constructor for B.
As a side note, you can use super(arg1, etc) to choose which constructor of A is called based on the parameter types you pass... but it must be the first line in the constructor.
The constructor contains all of the initialization for A. You are not creating two objects. You are creating one object, then running the initializer for the superclass to initialize its members, and then running the initializer for the deriving class to initialize its members.
It does not create two objects, it just creates one object b. b is of type B and of type A. A constructor is basically saying here is what you need to do to construct me. So when you are creating a new "B" instance, you are building an object that is both a B() and an A(). Imagine the following scenario:
class Q {
int i;
public Q() {
// set default value
i= 99;
}
}
class Z extends Q {
public Z() {
}
}
If the constructor for Q WAS NOT called, how would i get its default value?
The creation of B does not create an extra A.
But by creating B, you create a kind of A, because B is a A.
Java/C++ call the constructor of A for your implicitly. Why? Language design. But doing so is fine, because the constructor of A might contain some initializations. And as B uses all the features and bugs of A, these features better be initialized properly.
The constructor of a class is very important concept in most OOP
Classes, by providing state and the means to manipulate that state, allow the easier maintenance of invariants. The constructors role is to get the class into a state that conforms to those invariants (or throws thus forbidding usage of an invliad object).
this is somewhat looser than intended in many languages since the constructor is allowed to pass its own 'this' reference elsewhere but this is at least under the control of the class (as such it can know that it is in a sufficiently stable and valid state for it to be accessible to the rest of the world)
Inheritance makes this complex since B is-a A in a very real sense and thus can invoke any of the methods provided by A. The parts of B that are A should therefore get their chance to initialize themselves before B gets a look in, thus the constructor for A is called before the real work of the B constructor begins.
If A intializes members in it's constructor and you forget to call super in your derived class then the members of A could be in a bad state. Java is trying to stop you from shooting yourself in the foot.
Only one object is created, both contractors are running on the same object.
The reason is simple, as you know B has all the variables and methods of A, so if some variable of A needs initializing so methods of A can work someone has to initialize it - and that someone is A's constructor.
for example:
public class A {
public A() {
x = 1;
}
private int x;
public int getX() {
return x;
}
}
public class B extends A {
public B() {
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.getX()); // should print 1
}
}
When new object is create(B), inside B A object is created(because of extends keywords) . In B class JVM search B class constructor, but due to extends keywords it goes to super class constructor. inside A class x value is initialized. But x is private so that we can access outside class throw getXxx() method and get the result.
When sub class object is created then internally it was not created for super class object.But the memory should be allocated for super class members.
In java when you create an object of child class the constructor of parent class is always called because Object class is the parent of every super class and when you call the constructor of Object class then only your object is created and java does not support multiple inheritance in case of class so if you extends any other class then the relationship between you child class and the Object class is through the Parent class so to call the constructor of the Object class the constructor of Parent class must be called.
Every superclass has a constructor and each constructor up the hierarchy runs at the time an object of a subclass is created.
if super class object is not created then how sub class is accessing super class non static methods and variables.
I studied that non-static methods and variables can be accessed only through objects..

Why variables are not behaving as same as method while Overriding.? [duplicate]

This question already has answers here:
why java polymorphism not work in my example
(3 answers)
Closed 6 years ago.
Generally Overriding is the concept of Re-defining the meaning of the member in the sub class.Why variables are not behaving like methods while Overriding in java ?
For instance:
class Base {
int a = 10;
void display() {
System.out.println("Inside Base :");
}
}
class Derived extends Base {
int a = 99;
#Override
// method overriding
void display() {
System.out.println("Inside Derived :");
}
}
public class NewClass {
public static void main(String... a) {
Derived d = new Derived();
Base b = d;
b.display(); // Dynamic method dispatch
System.out.println("a=" + b.a);
}
}
Since data member a is package access specified, it is also available to the Derived class. But generally while calling the overridden method using the base class reference, the method that is redefined in derived class is called (Dynamic method dispatch)..but it is not the same for the variable..why.?
EXPECTED OUTPUT
Inside Derived :
a=99
OBTAINED OUTPUT:
Inside Derived :
a=10
Prints 10 - why the variable does not behave similar to method in the derived class?
Why the variables are not allowed to be overridden in the sub class?
You typed b as an instance of Base. So when the compiler needs to resolve b.a, it looks to the definition of Base for the meaning of b.a. There is no polymorphism for instance fields.
Because the only thing that polymorphism ever applies to in Java is instance method.
Hence, you can neither override static members, nor the instance member fields. By, having these members in a derived class with the same names you're simply hiding them with a new definition.
System.out.println("a="+b.a);
Although, Base b may point to a sub-class object (at runtime) the a above has already been bound to Base class at compile time (static binding). Hence, it prints 10.
Variables behave like that because they lack behavior. In other words, variables are passive.
There is nothing about a variable's definition that a derived class can reasonably change by overriding:
It cannot change its type, because doing so may break methods of the base class;
It cannot reduce its visibility, because that would break the substitution principle.
It cannot make it final without making it useless to the base class.
Therefore, member variables declared in derived classes hide variables from the base class.
There is no way to override a class variable. You do not override class variables in Java you hide them. Overriding is for instance methods.
In this case, it might be a good idea to write a getter method:
public int getA(){
return 99;
}
Now you can override it in a derived class.
First, we don't override any class variable. Methods only.
Second, if you would like to see that the variable value has been updated or replaced, you should rather declare it as "static int" instead of "int". In this way, it will work as everybody is sharing the same variable, and the new value will be put on it.
Third, if you would like to see that the variable value being assigned and used differently, you could design it as passing a parameter in constructor, or something similar, to make it work accordingly as you desire.
The answer to this has to do with variable scoping, not polymorphism. In other words, you're overriding that variable in the class scope. So, d.a will return the variable in Derived's class scope, but b.a will return the variable in Base's class scope.
In OOP (Object Oriented Programming) the idea is to hide the data in the object and let object only communicate with invoking methods. That's why variables cannot be overloaded, in fact they are "scoped"/"attached" to a specific class.
Also the derived class should not define a again, it is already defined in the base class, so simply set a on the object to the desired value, e.g:
class Base {
private int a = 10;
public int getA() { return a; }
public void setA(inta) { this.a = a; }
}
class Derived extends Base {
// adding new variables, override methods, ...
}
// then later:
Derived d = new Derived();
d.setA(99); // override the default value 10
What would happen if variables could override other variables? Suddenly your class has to be aware of what variables the parent class is using, lest you accidentally override one and break whatever was using it in the parent class. The whole point of encapsulation is to avoid having that kind of intimate knowledge of another object's internal state. So instead, variables shadow same-named other variables, and which one you see depends on what type you're trying to reach the variable through.
There's hope, though. If all you want is to override the value, you don't have to redeclare the variable. Just change the value in an init block. If the base class is harmed by you doing that, then it chose the wrong visibility for that variable.
class Base {
int a = 10;
}
class Derived extends Base {
{ a = 99; }
}
Of course, this doesn't work very well for final variables.
we don't override any class variable. Methods only.
If you would like to see that the variable value has been updated or
replaced, you should rather declare it as "static int" instead of
"int". In this way, it will work as everybody is sharing the same
variable, and the new value will be put on it.
If you would like to see that the variable value being assigned and
used differently, you could design it as passing a parameter in
constructor, or something similar, to make it work accordingly as
you desire.
Moreover, if variables are overridden then what is left with a parent class of its own,it breaches the class security if java would give the access to change the value of variable of parent class.

What is an attribute in Java?

I read that to get length of an array, I use the length attribute, like arrayName.length. What is an attribute? Is it a class?
An attribute is another term for a field. It's typically a public constant or a public variable that can be accessed directly. In this particular case, the array in Java is actually an object and you are accessing the public constant value that represents the length of the array.
A class is an element in object oriented programming that aggregates attributes(fields) - which can be public accessible or not - and methods(functions) - which also can be public or private and usually writes/reads those attributes.
so you can have a class like Array with a public attribute lengthand a public method sort().
Attribute is a public variable inside the class/object. length attribute is a variable of int type.
Attributes is same term used alternativly for properties or fields or data members or class members.
An attribute is an instance variable.
In this context, "attribute" simply means a data member of an object.
Attribute is a synonym of field for array.length
Attributes are also data members and properties of a class. They are Variables declared inside class.
A class contains data field descriptions (or properties, fields, data members, attributes), i.e., field types and names, that will be associated with either per-instance or per-class state variables at program run time.
An abstract class is a type of class that can only be used as a base class for
another class; such thus cannot be instantiated. To make a class abstract,
the keyword abstract is used. Abstract classes may have one or more
abstract methods that only have a header line (no method body). The method
header line ends with a semicolon (;). Any class that is derived from the base
class can define the method body in a way that is consistent with the header
line using all the designated parameters and returning the correct data type
(if the return type is not void). An abstract method acts as a place holder; all
derived classes are expected to override and complete the method.
Example in Java
abstract public class Shape
{
double area;
public abstract double getArea();
}
■ What is an attribute?
– A variable that belongs to an object.Attributes is same term used alternatively for properties or fields or data members or class members
■ How else can it be called?
– field or instance variable
■ How do you create one? What is the syntax?
– You need to declare attributes at the beginning of the class definition, outside of any method. The syntax is the following:
;

inheritance and class members

GIVEN:
class A
{
String s = "A";
}
class B extends A
{
String s = "B";
}
public class C
{
public static void main(String[] args){ new C().go();}
void go()
{
A a = new B();
System.out.println(a.s);
}
}
Question:
What are the mechanics behind JVM when this code is run? How come a.s prints back as "A".
Field references are not subject to polymorphism, so at compile time the compiler is referencing A's field because your local variable is of type A.
In other words, the field behavior is like the Java overloading behavior on methods, not the Java overriding behavior.
You probably expect fields to be overridden like method, with dynamic dispatch based on the runtime type of the object.
That's not how Java works. Fields are not overridden, they are hidden. That means an object of class B has two fields named "s", but which of them is accessed depends on the context.
As for why this is so: it wouldn't really make sense to override fields, since there is no useful way to make it work when the types are different, and simply no point when the type is the same (as you can just use the superclass field). Personally, I think it should simply be a compiler error.
This isn't polymorphism (as tagged).
Java has virtual methods, not virtual member variables - i.e. you don't override a property - you hide it.
Although member variables are inherited from a base class, they are not invoked polymorphically (i.e dynamic invocation does not apply to member variables).
So, a.s will refer to the member in the base class and not the derived class.
Having said that, the code is not following OO principles. The members of a class need to be private/protected (not public or default) depending on the business use case and you need to provide public methods to get and set the values of the member.

Categories

Resources