Understanding execution flow of this Java programme [duplicate] - java

This question already has answers here:
Why doesn't the compiler complain when I try to override a static method?
(9 answers)
Closed 6 years ago.
I'm new at learning Java can anyone explain me the execution flow of the following code? I'm quite confused with the output.
This is the code:
public class MainClass {
public static void main(String[] args) {
car c = new car();
vehicle v = c;
/* I am unable to understand what's happening while printing the values using the objects of the different classes*/
System.out.println("|" + v.getModelName()
+ "|" + c.getModelName()
+ "|" + v.getRegNo() + "|" + c.getRegNo() + "|");
}
}
class vehicle {
public static String getModelName() {
return "Volvo";
}
public long getRegNo() {
return 12345;
}
}
class car extends vehicle {
public static String getModelName() {
return "Toyota";
}
#Override
public long getRegNo() {
return 54321;
}
}

Object creation
You are creating car instance ( new car())
Add new object pointer to variable c
Copy content of variable c to variable vehicle ( which point to car object)
Method call flow
When you are call static function on object it will not apply inheritance rules, so in call to v.getModelName() Java Virtual Machine call method in class vehicle.
But when you are call car() object with vehicle pointer (v variable) getRegNo method of class vehicle will call and also when you are using car pointer (c variable) getRegNo method of class vehicle will call.
edite suggestion form comment:
This ability called "Polymorphism": here you can find good tutorial. "Polymorphism" is definitely as important a concept as "inheritance" and "encapsulation'.

Related

Java how to call method in another class

Sorry for the basic question but I'm learning, new to programming. I am trying to call a method that is in another class but I'm unable to without passing in the required values for the constructor of Cypher class. Do i really need a new instance of Cypher class each time i use a method in the Menu class and want to call a method of the Cypher class or how do I rewrite to avoid below.
public class Runner {
private static Cypher c;
public static void main(String[] args) {
Menu m = new Menu();
m.displayMenu();
//c=new Cypher(3,2);// wont work unless i add this line
c.displayCypher("text");
}
}
public class Cypher {
private int keyTotalRows;
private int keyStartRow;
public Cypher(int key, int offset) throws Exception {
}
public void displayCypher(String text) {
System.out.println("Plain text:" + text);
System.out.println("Key: Number of Rows:" + keyTotalRows + "\n" + "Key Start Row: " + keyStartRow);
}
}
public class Menu {
private Scanner s;
private void enterKey() {
s = new Scanner(System.in);
System.out.println("Enter key >");
int key = Integer.parseInt(s.next());
System.out.println("Enter offset >");
int offset = Integer.parseInt(s.next());
System.out.println(" Key:" + key + "\n" + " Offset:" + offset);
}
public static void displayMenu() {
System.out.println("Menu");
}
Few things:. Your methods are private which means you cannot call them outside the class.
change that and you will be able to create your object and call them.
Menu menu=new Menu() ;
menu.otherMethod();
However as the method calls c which is null you will get a null exception.
You should test for it and then call object c inner methods
If (this.c! =null)
{c.displayOtherCypherType("" ) ;}
else
{//do something here}
In order to be able to send Cypher from outside the class use a constructor that receives a Cypher object and assigns it to c or have a public set method that receives it and assigns it
public setCypher(Cypher cypher)
{
(this.c=cypher) ;
}
Now If you want to call Cypher methods without instantiating it you can create a static method inside it and call Tha method.
note that it to should be public or you won't be able to call it
You declare a Cypher type static variable c here. so you can't access the Cypher class method using c variable without object declaration. But you can call the c variable from any class because it's a static variable. But your Cypher class don't have any static Method so you can't call these methods without object initialization.
So you must declare a static method or need to create an object for the access method from Cypher class.
But if you declare Cypher type static variable with initialization. then you can call c from any class and also called Chyper class method using the c variable reference. like:
// Declare this on Runner class
public static Cypher c = new Cypher();
// And then call from any class like
Runner.c.yourMethod();
Happy Coding.
If you don't want to create an instance, you can make the method static.
Something like this:
public static void displayCypher(String text) {
System.out.println("Plain text:" + text);
System.out.println("Key: Number of Rows:" + keyTotalRows + "\n" + "Key Start Row: " + keyStartRow);
}
Then you can call this function in another class like
Cypher.displayCypher()

Using of methods instead of constructor [duplicate]

This question already has answers here:
Purpose of a constructor in Java?
(12 answers)
Closed 2 years ago.
When we can use methods instead of constructor for any operation then what is the use of constructor in java or c++.
//Program of Division using constructor:-
class Hey {
Hey() {
int i = 10;
System.out.println("Division of 10/2 is " + i/2);
}
}
public class HelloWorld extends Hey {
public static void main ( String[] args ) {
Hey ob = new Hey();
}
}
//Program of division using method:-
class Hey {
public void disp() {
int i = 10;
System.out.println("Division of 10/2 is " + i/2);
}
}
public class HelloWorld extends Hey {
public static void main( String[] args ) {
Hey ob = new Hey();
ob.disp();
}
}
As, we can see that both will have same output. So, now I am bit confuse that when to use constructor.
Constructor is used to initialize objects in java. Even if you don't provide constructor in your code, java compiler will automatically add a default constructor.
Whereas Methods are used to exhibits functionalities to object. You will have to invoke methods explicitly in your code.
In the example you shared, you are creating object of Hey class Hey ob=new Hey() in order to call its method disp. So if you want to define object in your class, you will use constructors, and if you want to write some functionality of object, you can use Methods.

Java upcasting issue [duplicate]

This question already has answers here:
Does polymorphism apply on class attributes in Java?
(8 answers)
Closed 4 years ago.
I have a following code
public class Main {
public static void main(String[] args) {
Parent upCasted = new Child();
System.out.println("String: " + upCasted.getString());
System.out.println("Int: " + upCasted.a);
}
}
class Parent {
int a = 1;
public String getString() {
return "Parent";
}
}
class Child extends Parent {
int a = 2;
#Override
public String getString() {
return "Child";
}
}
When I run it I see this in console
String: Child
Int: 1
Why during the upcasting the int value was taken from the Parent and the String value from the Child?
It's because instance fields are not overridden when re-declared in child classes.
Instead, when upCasted.a is evaluated, Java looks at the static/declared type of upCasted to know which class's field to read (not at the runtime class of the object that upCasted points to).
This is why one should not use the same name for fields in superclasses and subclasses.

Can a Java object factory be used as a constructor?

I'm pretty new to Java so hopefully this question isn't too stupid.
According to the Java documentation: "An object factory is a producer of objects. It accepts some information about how to create an object, such as a reference, and then returns an instance of that object."
How can that instance be the result of a constructor?
Here is some (totally pointless) example code that illustrates the class hierarchy I'm trying to construct (invoking it with simple integer arguments like "1 2 3" will get the point across):
package number;
public class Factory {
public static void main(String[] args) {
for (String arg : args) {
// This is how I want to instantiate and use the Outer class:
Outer outer = new Outer(arg);
// But I don't know how to create Outer from the factory, and the results are wrong:
System.out.println("yields: " + outer.value + ", class: " + outer.Class());
// This is a workaround (that I can't use) that gives the correct results:
Number number = outer.Workaround(arg);
System.out.println("yields: " + number.value + ", class " + number.Class());
}
}
}
class Outer extends Inner {
Outer(String arg) {
super(arg);
}
}
class Inner extends Number {
Inner(String arg) {
// I don't want to do this:
super(arg);
// I want some way of doing this:
// return NumberFactory.getNumber(arg);
}
// Workaround method that I can't really use:
Number Workaround(String arg) {
return NumberFactory.getNumber(arg);
}
}
class NumberFactory {
static Number getNumber(String selection) {
switch (selection) {
case "1": return new First(selection);
case "2": return new Second(selection);
default: return new Other(selection);
}
}
}
class First extends Number {
First(String arg) { super(arg); value = "first"; }
String Class() { return "First"; }
}
class Second extends Number {
Second(String arg) { super(arg); value = "second"; }
String Class() { return "Second"; }
}
class Other extends Number {
Other(String arg) { super(arg); value = "other"; }
String Class() { return "Other"; }
}
class Number {
String arg;
String value = "default";
Number(String arg) {
this.arg = arg;
System.out.print("Number(" + arg + "), ");
}
String Class() { return "Number"; }
}
please explain what you are trying to do.
but here's my attempt to answer your question.
Constructor is used when ever a new Java Object is created. When you use new SomeObject() compiler uses the constructor
SomeObject(){
// some logic here
}
to create an object using the SomeObject.class. How the object is created and maintained through its life-cycle is up to the JVM. you can find more info here. https://en.wikibooks.org/wiki/Java_Programming/Object_Lifecycle
Also object factories are used to create objects, but in turn they use object constructors to instantiate the object inside them (as you have already done so).
Object factories are used to delegate the logic of object creation to a central location, so that the code is not repeated and well organized.
Read more about object factories here https://github.com/iluwatar/java-design-patterns/tree/master/abstract-factory
another thing you dont have to implement String Class() method inside every class you implement. SomeObject.class.toString() will do it for you.
I couldn't understand your main question because java object factory is java's business and I don't think we can do anything with it, although I can try to answer your question regarding instances and constructor.....
Constructors in java are the way you talk to a class, even when you don't define a constructor of a class, a default constructor with default values(i.e., false for boolean etc.) is created for your class by the compiler.....So, I guess when you want specific way of creating a connection with your class then you make specific constructors otherwise a default is always made available by the compiler.
Maybe you want to ask why do we have to use super() before anything in a subclass constructor and the reason for that is again same i.e., The parent class' constructor needs to be called before the subclass' constructor. This will ensure that if you call any methods on the parent class in your constructor, the parent class has already been set up correctly.

Java inheritance - access private variable / getClass() [duplicate]

This question already has answers here:
Java: Calling a super method which calls an overridden method
(13 answers)
Closed 5 years ago.
Question: The result of the following code is "5 A" and "10 B". How is it possible that for b.print(), this.num is a reference to a Class A object and this.getClass() is a reference to a Class B Object?
Superclass A
public class A {
private int num;
public A(int num) {
this.num = num;
}
public void print() {
System.out.println(this.num + " " + this.getClass().getName());
}
}
Subclass B
public class B extends A {
public B(int num) {
super(num);
}
}
Main Method
A a = new A(5);
B b = new B(10);
a.print();
b.print();
These are two distinct things.
this.getClass() or more simply getClass() (as this is implied as not specified) will always refer to the actual runtime class that may be the class that uses it or a child of it. If you call it from A, it will return the A class but if you call it from a child of it, it will return this child class.
While this.num refers to a specific instance field declared in the A class. When you code refer to this field, it relies necessarily on the class that declares this specific field.
Whenever you call this in an instance, you are going to be calling the actual instance, and not the "class". For example, in you case, if you override the method print in your class B, like this;
public class B extends A {
public B(int num) {
super(num);
}
public void print() {
System.out.println("PRINTING B");
}
}
Then when you call the print method it will call this one and not the parent one, even if you use this.print() inside any method of the class A
If you really want to explicitly print the A class, then you need to reference it like this:
public void print() {
System.out.println(this.num + " " + A.class.getName());
}

Categories