Java Inheritance issue - java

While exploring for scjp questions, I came across this behaviour which I found strange.
I have declared two classes Item and Bolt as follows:
class Item {
int cost = 20;
public int getCost() {
return cost;
}
}
class Bolt extends Item {
int cost = 10;
public int getCost() {
return cost;
}
}
and tried to access the value of cost twice
public class Test {
public static void main(String[] args) {
Item obj = new Bolt();
System.out.println(obj.cost);
System.out.println(obj.getCost());
}
}
The output I get is 20 10.
I can't understand how this happens.

obj is a reference of type Item hence the first 20 since the value of cost field of Item is 20. The second value is 10 because the runtime type of obj is Bolt and hence getCost() invokes getCost of Bolt class (since Bolt extends Item).
In short, runtime polymorphism is applicable to only instance members (method overriding) and not instance fields.

Class fields do not participate in polymorphism game. The methods do.
So, when you access the field you go to one that is defined in base class because you object's type is Item. When you call method you get the actual value because you invoke method using polymorphism.
Conclusion:
Fields are always private. If you want to access field write method.

Related

Cannot pass super keyword as an argument to method in java

Why below program does not work fine?
instead of super in below code if we give this keyword as an argument it will work fine, what is the difference between two codes.
Thanks in advance
class Vehicle
{
int maxSpeed = 120;
}
/* subclass Car extending vehicle */
class Car extends Vehicle
{
int maxSpeed = 180;
void display()
{
test(super);
/* print maxSpeed of base class (vehicle) */
// System.out.println("Maximum Speed: " + super.maxSpeed);
}
public void test(Vehicle obj)
{
System.out.println("Maximum Speed: " + obj.maxSpeed);
}
}
/* Driver program to test */
class Test
{
public static void main(String[] args)
{
Car small = new Car();
small.display();
}
}
There is a misconception on your end. this refences to a real object, therefore you can pass it to any method that allows for an instance of the corresponding class.
But there is no separate super object! super is nothing but a helper mechanism that allows you to access methods or fields of the super class (and it only works within a derived class). It is not intended to deliver a real object refence!
And note: that also doesn't make sense conceptually. You can't really separate the super class properties when looking at a child class due to polymorphism.
It is really simple: you pass this, nothing else. If your code doesn't work then, then that would be a symptom of a bug in your design!
Welcome to StackOverflow.
Your method test receives a instance of a Car, and keyword super it's used to call parent methods, through child class. this keyword returns the instance of the class.
What you're trying to achieve is call super() constructor to pass a instance of a Car to the method, but java states that the the super() call can be used only once in the constructor class as the first statement, to ensure that class will inherit from it's parent, or Object class directly. If you not states it, Java implicitly does it for you.

If I assign a value to a variable inside a method, does it persist beyond the scope of that method?

Sorry if this is a repeat, i've tried looking for the answer to my question but could not come across the answer I'm after.
I'm very new at Java (literally started yesterday) and I am trying to understand why if I declare a variable in my class and then assign a value to it in a void method, the value associated with that variable persists beyond the method's scope. My (very) limited understanding of methods is that they have their own scope and I thought the only way to access any variable changes that had been made within a method was to return them at the end of the method. Is this not the case?
Each method in a class will inherit any attribute (variable) or any method that directly belongs to that class. Say
public class Bicycle {
public int gear;
public int speed;
// the Bicycle class has
// two methods
public void setGear(int newValue) {
gear = newValue;
}
public void speedUp(int increment) {
speed += increment;
}
}
Let's get the setGear method
public void setGear(int newValue) {
gear = newValue;
}
As you can see, I can access the 'gear' attribute because it belongs to the Bicycle class. The parameter '(int newValue)' belongs to this method exclusively, meaning I can only access this variable inside this method, like this:
public void setGear(int newValue) {
newValue = gear;
//this wouldn't make much sense logic wise, but it is
//valid code since I can use newValue only inside the setGear method
speedUp(10);
//the method 'speedUp' belongs to the bicycle class, so I can use
//it inside another method belonging to the same class
}
Alternatively, I can use the this keyword to say that I am referring class attributes, like this:
public void setGear(int gear) {
this.gear = gear;
//I am telling the method that the class attribute 'gear' will
//receive my parameter value 'gear'
//this is useful when my parameter variable name has the same
//name as my class attribute
}
Edit: forgot to give credit to the oficial oracle docs https://docs.oracle.com/javase/tutorial/java/javaOO/classes.html
The answer to this is a bit more complex.
First start to distinguish a method from a function.
A method operates on an object instantiated by calling the constructor of the class (e.g. MyClass obj = new MyClass();). From this point, your object has a state expressed by it's member variables (all variables that are not declared static in your class).
Methods (as part of the object) may change this state (unless the corresponding variables are declared final).
To be able to to so, a method inherits the scope of the class, but the variables are bound to the instance of the object, on which the method is called.
So for instance:
public class MyClass {
private int a = 0;
public void aplusplus() {a++;}
}
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
obj1.aplusplus(); // the a of obj1 is now 1
obj2.aplusplus(); // the a of obj2 is now 1
obj1.aplusplus(); // the a of obj1 is now 2
But beware! There is also a concept called hiding.
If you declare a local variable within the body of a method, it hides the class member variable. Accessing the variable by name results in accessing the local variable, instead of the member variable. This is particuallry interesting when implementing setter methods for private members, where usually the argument of the method (which is a local variable) is named exactly as the member variable. To still access the member variable, you can use this.variablename. For instance:
public class MyClass {
private int a = 0;
public void aplusplus() {a++;}
public void setA(int a) {this.a = a;}
}
You say in your question that you have declared a variable in your class. This means that any value the variable gets set to, (during method invocations), will persist across method invocations. The variable is part of this object, and as such, is referred to as an instance variable.
If you declare variables inside method definitions, they are inside the scope of the method. They are part of this.yourMethod(). These variables are said to be local to the method. You can only use these variables inside the method. The this object does not know they exist.

Why "int" doesn't get inherited in java?

class Number {
int mark;
}
class One extends Number {
mark = 1; //error: variable mark not initiated.
}
It's because I have to use it in a method:
int getMark( Number n) {
return n.Mark;
//returns 1 if Object passed is of "One" class
}
So why is that error showing in line 5 of first code.
Edit: Typo, It's "Number" only.
Your initialization code in the subclass needs to occur inside a constructor, method, or initializer block. Something like this (using a constructor):
class One extends Number {
public One() {
mark = 1;
}
}
or like this (using an initializer block):
class One extends Number {
{
mark = 1;
}
}
See the Java tutorial topic Initializing Fields for more information. (By the way, Number is a terrible class name because it collides with a class name in java.lang that every Java program implicitly imports.)
It would be better, however, to put the initialization of mark in the code for Number, since it is good programming practice to keep the management of the field in the same class in which it is declared. This can be done by defining an appropriate constructor for Number:
class Number {
int mark;
/** Explicit initialization constructor */
Number(int mark) {
this.mark = mark;
}
/** Default constructor (perhaps not needed?) */
Number() {
// assign default value to mark (if 0 is not a good default)
}
}
class One extends Number {
One() {
super(1); // calls the explicit initialization constructor
}
}
Eventually, you should also give some thought to what access specifiers (public, protected or private) would be appropriate.
As far as referencing the variable in the method getMark, the problem there is that mark is not the same as Mark. Java is case sensitive when it comes to variable names. Rewrite the method to refer to the variable correctly:
int getMark( Number n) {
return n.mark;
//returns 1 if Object passed is of "One" class
}
I would also suggest making getMark() a method of your Number class, rather than an external method. Then you could use n.getMark() instead of getMark(n) to get the current value of mark. You could then declare mark to be private (and perhaps final as well), since encapsulation and immutability are always good things in OOP.

In which situations we make variables as public and methods as private?

Currently I am learning basics of java and C++. I have read in book Let Us C++, that in almost every case we we make instance variables private and methods public for the security purposes. But it is also mentioned in this book that in some cases we make variables public and methods private..
I am continuously thinking, in which cases we will do so. Can anyone please explain this.
Private methods (or private member functions in C++ terminology) are mostly useful as helper functions. For example, think of the case that you want to implement fractions, but want to ensure that your fraction is always normalized. Then you could use a private member function normalize() which normalizes your fraction, and which is called after each operation which might result in a non-normalized fraction, for example (C++ code):
class Fraction
{
public:
Fraction(int num, int den = 1);
Fraction operator+=(Fraction const& other);
Fraction operator*=(Fraction const& other);
// ...
private:
int numerator, denominator;
};
Fraction::Fraction(int num, int den):
numerator(num),
denominator(den)
{
normalize();
}
Fraction Fraction::operator+=(Fraction const& other)
{
int new_den = denominator*other.denominator;
numerator = numerator*other.denominator + denominator*other.numerator;
denominator = new_den;
}
Fraction Fraction::operator*=(Fraction const& other)
{
numerator *= other.numerator;
denominator *= other.denominator;
normalize();
}
void Fraction::normalize()
{
int factor = gcd(numerator, denominator);
numerator /= factor;
denominator /= factor;
}
Another, C++ specific use of private functions is based on the fact that in C++ private is only about access control, not about visibility. This enables to do unoverridable pre-post-condition checking in the base class while making the actual function virtual:
class Base
{
public:
foo frobnicate(some arguments);
private:
virtual foo do_frobnicate(some arguments) = 0;
};
foo Base::frobnicate(some arguments)
{
check_precondition(arguments);
foo result = do_frobnicate(arguments);
check_post_condition(foo);
return foo;
}
Classes derived from Base will override do_frobnicate, while users will call frobnicate which always checks the pre/postconditions no matter what the derived class does.
Generally static final variables are public in a class. If you don't need to change the value of that variable and want other classes to access it then you make it public static final.
Private methods are used only within the class for doing the task, which is internal to that class. Like a utility method or some business calculation method. Or simply to break the code of public method into multiple private methods, so that methods don't grow too big.
When a method is to be used by other methods(public) of the class and you do not want the object to access that method directly, we make that method as private.
And in some cases, if you want to access your variable directly from the class object, then make it public.
If you don't need the varibale or methode in other classes don't make it public. This goes for methodes and variables.
private methods are for the internal use of the class. They can be called from other public classes. Those are private because you encapsualted from outer world.
For example
public void method1(){
method2();
}
private void method2(){
// for internal use
}
Public variables are mainly used for class variables in which cases there is no harm of direct accessing the variables from outside. For example
public static final int FLAG = true;
You can directly call the variable from outside.
It depends how much security you want for each class.
For example, if you have a Vector class, that only has 3 variables x, y and z, you should make them public. Many classes will probably use the Vector class and it's fine if they change values in it.
If you have a Person class that stores credit card number, background record, address etc, you should make them private to avoid security issues.
However, if you have all variables as private, and you provide accessors and mutators for all of them, you're effectively making them just like public (but with more work).
EDIT:
All constant variables should be public, because you cannot change them anyway.
Static variables could be both, depending on a situation. Probably better to have static get and set functions for static variables.
Private variables or functions can be use only in the class where they are declarated.
Public variables or functions can be use everywhere in your application.
So you should declarate private all those variables and functions that you are going to use ONLY in the class where they belong.
Example:
public class Car {
private String model;
public setModel(String model) {
if (model != null)
this.model = model;
}
public getModel() {
return model;
}
private doSomething() {
model = "Ford";
}
}
In the class Car we declarate the String model as private because we are going to use it only in the class Car, doing this we assure that other classes couldn't change the value of this String without using the function setModel.
The functions setModel and getModel are public, so we can access the private variable model from other classes ONLY using those methods.
In this example, the function setModel checks if the value its null, in which case it doesn't set the value. Here you can see that if you had declarated the String model as public, you wouldn't have control over what value it's being recorded.
The function doSomething is private and other classes can't use it. For other side, like this function is private and it belong to the same class where is the String model, it can change its value without using the method setModel.
A rule of thumb, you make methods public when it is okay for other classes to access them. internal methods or helper methods should either be protected or private.Protected if you want the method to be extendable by those extending your class however if you don't want this just mark them private.

Problem in instance variable initialization

Heres some sample code,
class Base
{
private int val;
Base() {
val = lookup();
}
public int lookup() {
//Perform some lookup
// int num = someLookup();
return 5;
}
public int value() {
return val;
}
}
class Derived extends Base
{
private int num = 10;
public int lookup() {
return num;
}
}
class Test
{
public static void main(String args[]) {
Derived d = new Derived();
System.out.println("d.value() returns " + d.value());
}
}
output: d.value() returns 0 // I expected 10 as lookup() is overridden, but not 0! can someone clarify this?
The initialization of Derived's instance variables has not happened at the time its lookup method executes. How do I make sure the instance variables of Derived are initialized when its method is called?
Well for a start, that code doesn't compile due to the lack of someLookup method.
Anyway, asides from that I believe your issue is that your expections are invalid because of the way constructors are run hierarchically.
A superclass' constructor is always run before the subclass', and this includes initializers for the subclass' variables (which are really run as part of the constructor). So, when you create your instance of Derived, the following happens:
The Base constructor is invoked first.
lookup() is called, which uses the implementation in Derived.
num is returned, which is the default value at this point because Derived's constructor and initializers have not been run.
val is set to 0.
The Derived initializers and constructor are run - calling lookup from this point on will return 10.
In general, it's a bad idea to call a non-final method from a constructor for exactly this reason, and many static analysis tools will warn you against it. It's similar to letting object references leak during construction, you can end up with an instance that invalidates class-level invariants (in your case, Derived's num is "always" 10 yet it can be seen to be 0 at some points).
Edit: Note that for this particular case, without any additional code, you could resolve the issue by making num a constant:
class Derived extends Base
{
private static final int num = 10;
...
This would actually do what you want, because the static initializer is run when the class is loaded (which has to happen before the constructors are called). This does however assume that it's fine for:
a) all instances of the class to share the same num variable;
b) num never needs to change (if this is true then (a) is true automatically).
In the exact code you've given this is clearly the case, but I expect you may be omitting extra functionality for brevity.
I include this here for comparison and interest, not because it's a workaround to this "issue" in a general sense (because it's not).
The reason you are getting 0 returned is that the constructors Base is being called (and calling lookup in Derived) before 10 is assigned to num in Derived.
To put generally, the base constructor is called before the derived instance fields are initialised.
There are a lot of great answers already on why you can't access subclass fields while constructing the base class, but I think you asked for a how: a working solution for something like this:
public abstract class Animal {
public Animal() {
System.println(whoAmI());
}
public abstract String whoAmI();
}
public Lion() extends Animal {
private String iAmA = "Lion";
public Lion(){super();}
public String whoAmI() {return iAmA;}
}
The practical way is to introduce an init() method on the base class an call it from the subclass's constructor, like:
public abstract class Animal {
private boolean isInitialized = false;
public Animal() {}
void init() {
isInitialized = true;
System.out.println(whoAmI());
}
public abstract String whoAmI();
public void someBaseClassMethod() {
if (!isInitialized)
throw new RuntimeException("Baseclass has not been initialized");
// ...
}
}
public Lion() extends Animal {
private String iAmA = "Lion";
public Lion() {
super();
init();
}
public String whoAmI() {return iAmA;}
}
Only problem is, you can't force subclasses to call the init() method on the base class and the base class might not be properly initialized. But with a flag and some exceptions we can remind the programmer at runtime that he should have called init()...
It is generally a bad idea to call methods in a constructor that can be overriden in a subclass. In your example the following happens:
Derived constructor is called
Base constructor is called as its first action
Base constructor calls lookup
Derived constructor continues and initialies num to 10
Since the subclass constructor is not finished when the base constructor calls lookup, the object is not yet completely initialized and lookup returns the default value of the num field.
Let's take it slowly:
class Test
{
public static void main(String args[]) {
// 1
Derived d = new Derived();
// 2
System.out.println("d.value() returns " + d.value());
}
}
Step 1, you call the (default) constructor on Derived, before setting num = 10, it chains up to Base's constructor, which calls Derived's lookup method, but num has not been set, so val remains uninitialized.
Step 2, you call d.value(), which belongs to Base, and val is unset due to 1, and therefore you get 0 instead of 10.
You have overriden method lookup() in the Derived class, so when the Base constructor is called it calls the method from Derived which body is return num. At the time of Base initialization the num instance variable of the Derived is not yet initialized and is 0. That's why val is assigned to 0 in Base.
If I understood your intentions correctly, you should change the value method in Base to be:
public int value() {
return lookup();
}
The below piece of code is returing 0 (you would expect 10 by looking at the program) when the constructor makes a call to this. The simple reason is that num is not initialized yet and the parent class calls this method.
public int lookup() {
return num;
}

Categories

Resources