Please sorry me for that newbie question. This is for my so strange, because before java coding, I have had a C++ background, where variable by default is equal to undefined or null;
So I have a abstract class:
public abstract class Animal {
int lifeBar;
public void eat(int x) {
lifeBar += x;
}
}
And I have Bird class which extends it:
public class Bird extends Animal {
}
And Main class:
public class Main {
public static void main(String[] args) {
Animal bird = new Bird();
bird.eat(10);
System.out.println("bird: " + bird.lifeBar);
}
}
I thought that there should be compilation error, because I didn't declare lifeBar variable, but the console showed me 10. Why is that? Is it because there some default constructor?
Inheritance means subclasses can extends the state of superclass
hence in your example, when Bird extends Animal all the methods and
variables are inherited in Bird class.
lifeBar is an instance variable of type int hence its default value is 0
YOu are calling the method in which lifeBar += x; statement increments the value by 10 because you are passing 10 as argument to method.
lifeBar is member of Animal which isn't initialized explicitly, so it sets its default value that is 0 for int
See
default value of different types
Related
Consider an interface and its implementation,
interface A {
int a;
default void add() {
a = a+10;
}
public void sub();
}
class X implements A {
public sub() {
a = a-5;
}
}
I have to use the variable a in sub() function of class X. How can I do?
All variables declared inside interface are implicitly public static final variables(constants).
From the Java interface design FAQ by Philip Shaw:
Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
Since interface doesn't have a direct object, the only way to access them is by using a class/interface and hence that is why if interface variable exists, it should be static otherwise it wont be accessible at all to outside world. Now since it is static, it can hold only one value and any classes that implements it can change it and hence it will be all mess.
Hence if at all there is an interface variable, it will be implicitly static, final and obviously public!!!
The field a in the interface A always final and static and it isn't supposed to be modified in any way including reassigning it in an instance method.
Interfaces don't have the state. Abstract classes may.
abstract class A {
protected int a;
public void add() {
a += 10;
}
public abstract void sub();
}
final class X extends A {
public void sub() {
a -= 5;
}
}
I would use an abstract class instead of an interface. That way the variable can be modified by the extending class.
abstract class A{
int a=10;
void add(){
a=a+10;
}
public abstract void sub();
}
class X extends A{
public void sub(){
a=a-5;
}
}
Yes, We can use abstract class.
Since in interface variables declared are by default final.
Code with Interface
Code with Abstract Class
I have created one interface which looks like below:
public interface CalculatorInterface
{
int x=10; int y=15; int z=x+y;
public void add1();
}
Then i created one class which is implementing it. The class looks like below:
public class AdvClass2 implements CalculatorInterface {
public static void main(String[] args) {
int x=50;
System.out.println("X value is" +x);
}
#Override
public void add1() {
System.out.println("I am in Add Method");
}}
But the rule says i am not allowed to change interface variable value right. Can somebody tell me what am i doing wrong?
Variables in interface are by default static final ( you can call it as static constant ) variables ,so you can assign value to it only once , it's value cant be changed afterwards.
check this site for final keyword - https://www.javatpoint.com/final-keyword
You are actually changing the local variable in the main function. This variable is different from the one you declared in the interface which is indeed public, static and final by default. But there are no such restrictions on local variables.
Also if there is a variable with same name in the local scope then that variable is preferred over the variable with same name in the outer scope.
Edit:
As I explained earlier you are declaring x as local variable in main function and it is different from the variable x in the interface. In your main function do the following if you want a compile error while trying to change the interface x variable:
public static void main(String[] args) {
x=50;
System.out.println("X value is" +x);
}
Now you will see a compile error telling you the interface's x variable cannot be assigned.
Since an interface can not be instantiated directly, the interface variables are static and final by default. We are not allowed to change them.
Interfaces can't contain any implementation. A Java interface can only contain method signatures and fields.
I think you need a better design. So the interface should be like:
public interface ICalculator {
public int add1(int a, int b); // this is the method signature, not the implementation.
}
Then in the AdvClass2 you can implement the add1 method:
#Override
public int add1(int a, int b) {
int result = a + b;
return result;
}
In the below code, why is the super still referring to the subclass variable, and not the super class variable?
class Feline {
public String type = "f ";
public Feline() {
System.out.print("feline ");
}
}
public class Cougar extends Feline {
public Cougar() {
System.out.print("cougar ");
}
public static void main(String[] args) {
new Cougar().go();
}
void go() {
type = "c ";
System.out.print(this.type + super.type);
}
}
What subclass variable? You haven't declared one, so this.type refers to the superclass's variable.
If you declared public String type; in both the superclass and the subclass, it will work the way you are expecting. But right now, the only type variable you've declared is the one on the superclass.
Also, shadowing variables like this is bad practice, as it easily gets confusing as to what type you mean.
Firstly, you don't have subclass variable "type". Hence you are using super(parent) class variable(which is public available for both super and subclass) in the subclass. Hence when you change
type="c"
Super class variable is changed and hence this.type and super.type prints c
Hence in order to get your output, declare "type" in subclass.
public class Cougar extends Feline {
private String type = "f"; //or something else and see the output.
}
When the object of child class is created, the memory is allocated to instance member of the classes in the hierarchies.
There is only one copy in the memory for instance member type that is assigned for super-class but the visibility of that instance variable is public that why you can access it in child class as well using this.type but internally it's same location in the heap that is allocated for that object.
so this.type will change the value of instance member type defined in super class.
Summary: Child class is not defining a new instance member type instead it's inherited from super class.
Read What is purpose of using inheritance?
When type='c' is done in the subclass, it makes the super-class variable hidden, so that the super class variable is no longer available. Hence both this.type and super.type returns the value available ie, 'c', as type='f' is not visible to the code.
At the same time, if we change type='c' to String type='c' here we are creating a local variable, and not overriding the super-class variables. Hence the solution for
public class Feline {
public String type = "f ";
public Feline() {
System.out.println("In 1....feline ");
}
}
public class Cougar extends Feline
{
public Cougar() {
System.out.println("2.....cougar ");
}
public static void main(String[] args) {
new Cougar().go();
}
void go() {
String type = "c ";
System.out.println(this.type + super.type);
System.out.println("Subclass type::"+type);
System.out.println("this.type::"+this.type);
System.out.println("super.type::"+super.type);
}
}
The output is::::::: In 1....feline
2.....cougar
f f
Subclass type::c
this.type::f
super.type::f
In this case a new local variable is created, therefore the super-class variable is not hidden
Please have a look at this code :
class Foo {
public int a;
public Foo() {
a = 3;
}
public void addFive() {
a += 5;
}
public int getA() {
System.out.println("we are here in base class!");
return a;
}
}
public class Polymorphism extends Foo{
public int a;
public Poylmorphism() {
a = 5;
}
public void addFive() {
System.out.println("we are here !" + a);
a += 5;
}
public int getA() {
System.out.println("we are here in sub class!");
return a;
}
public static void main(String [] main) {
Foo f = new Polymorphism();
f.addFive();
System.out.println(f.getA());
System.out.println(f.a);
}
}
Here we assign reference of object of class Polymorphism to variable of type Foo, classic polmorphism. Now we call method addFive which has been overridden in class Polymorphism. Then we print the variable value from a getter method which also has been overridden in class Polymorphism. So we get answer as 10. But when public variable a is SOP'ed we get answer 3!!
How did this happen? Even though reference variable type was Foo but it was referring to object of Polymorphism class. So why did accessing f.a not result into value of a in the class Polymorphism getting printed? Please help
You're hiding the a of Polymorphism - you should actually get a compiler warning for that. Therefore those are two distinct a fields. In contrast to methods fields cannot be virtual. Good practice is not to have public fields at all, but only methods for mutating private state (encapsulation).
If you want to make it virtual, you need to make it as a property with accessor methods (e.g. what you have: getA).
This is due to the fact that you can't override class varibles. When accessing a class variable, type of the reference, rather than the type of the object, is what decides what you will get.
If you remove the redeclaration of a in the subclass, then I assume that behaviour will be more as expected.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
this and super in java
I'm new to development. Something that I'm still unable to understand is the difference between this and super keywords. If there are any answers, it would be highly appreciated. Thanks.
this
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
super
If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a hidden field (although hiding fields is discouraged).
super refers to the base class that the current class extends. this refers to the current class instance.
So, if Parent extends Child and you create a new Child(), super refers to the Parent class (and doing something like super() in the constructor would call the parent's constructor) and this refers to the actual Child instance you created with new.
Super refers to the superclass that a class extends. this refers to the current instance of a class.
These concepts can be confusing for new developers, they will be more clear when you learn about extending classes (inheritance). Sometimes when you refer to a variable or method, you might be being ambiguous for example if you repeated a class variable name in a method, the compiler won't know which variable you are referring to, so you can use this to specify you are referring to the current class's variable (not the local variable). The following would be ambiguous (and WRONG):
class Bike
{
int speed = 10;
public setSpeed(int speed)
{
speed = speed;
}
}
The compiler would have no idea what you intended, and will probably insult you with a cryptic (for a new developer) error message. Using this in the following way tells the compiler "I am referring to the class level variable, NOT the method level variable"
class Bike
{
int speed = 10;
//Constructors and shiz
public void setSpeed(int speed)
{
this.speed = speed;
}
}
(Although in practice you shouldn't duplicate variable names in this way!)
So to summarise, this tells the compiler that you're referring to the CURRENT class. Further ambiguity can arise when you extend classes (inherit functionality for a parent or super class), because the option of overriding the parent method arrises.
class Bike
{
public Bike()
{}
public void printSpeed()
{
System.out.println("This generic bike can go 10 m/s!!");
}
}
Now if we were to extend the bike class by introducing a more specific type of bike, we may want to override the printSpeed method to give the speed of our shiny new bike, like so:
class MountainBike extends Bike
{
public MountainBike() {}
public void printSpeed()
{
System.out.println("WHOAAAH!! MOUNTAIN BIKE GOES 100 m/s!!");
}
public void printGenericSpeed()
{
super.printSpeed();
}
}
The super.printSpeed() tells the compiler to run this method from the parent class, so a call to super.printSpeed() would actually call the printSpeed() method in the Bike class. The following code:
public static void main(String args[])
{
MountainBike mb = new MountainBike();
mb.printSpeed();
mb.printGenericSpeed();
}
will print
WHOAAAH!! MOUNTAIN BIKE GOES 100 m/s!!
This bike can go 10 m/s!!
Note that if we had not overridden the printSpeed() method, calling the following would be a call to the printSpeed() method of the Bike class.
public static void main(String args[])
{
MountainBike mb = new MountainBike();
mb.printSpeed();
}
would print
This bike can go 10 m/s!!
So to conclude, we use this to refer to the current class we're in, and super to refer to the parent of the class we're in.
In Java the keyword this refers to the current object of a class, like in:
class Point {
public int x = 0;
public int y = 0;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return x + "," + y;
}
}
class Point3D extends Point {
public int z = 0;
public Point(int x, int y, int z) {
super(x,y);
this.z = z;
}
public String toString() {
return super.toString() + "," + z;
}
}
In the constructor of the class Point this.x refers to the x defined in the class, where x is the parameter passed into the constructor. Here this is used to resolve the ambiguity of the name x. The same thing is true for y.
In the class Point3D the method toString() uses the return value of the super class Point to produce its own return value.
this: is the reference to the current object in the methods of its class. Refer to any member of the current object through the this keyword.
super: is the derived class' parent when your class extends it through the extend keyword, and you can invoke the overridden method through the use of the keyword super. You can also use super to refer to a protected fields.
this keyword refers to the current instance at that point in time.
super keyword refers to the parent/super class of the current class.
EX:
class Test
{
Test()
{
}
Test(int i)
{
System.out.println("i=" + i);
}
}
class Sample extends Test
{
int i;
void Sample(int i) //constructor
{
this.i=i; // referring class version of the i using 'this'
super(i); // passing parameter to Super/Parent class constructor.
}
}