Java recursion and inheritance - java

I have two classes like below:
public class Animal {
public void askForLocation() {
System.out.println("In animal");
System.out.println("Street?");
Scanner inFromConsole = new Scanner(System.in);
String street = inFromConsole.nextLine();
if (street.equals(""))
this.askForLocation();
else
System.out.println("Street: " + street);
}
}
}
public class Dog extends Animal {
#Override
public void askForLocation() {
Scanner inFromConsole = new Scanner(System.in);
System.out.println("In dog");
String city;
super.askForLocation();
System.out.println("Back in dog");
System.out.println("City?");
city = inFromConsole.nextLine();
System.out.println("city: " + city);
}
}
Then I run the following code:
public class TestAnimals {
public static void main(String[] args) {
System.out.println("----");
Dog doggy = new Dog();
doggy.askForLocation();
}
}
When I give an empty string as an argument for street the first time I get the following output:
1 In dog
2 In animal
3 Street?
4
5 In dog
6 In animal
7 Street?
8 Main Street
9 Street: Main Street
10 Back in dog
11 City?
12 NY
13 city: NY
14 Back in dog
15 City?
16 NY
17 city: NY
It's two things that I don't understand:
In line 5 of the output the call to askForLocation is a call to askForLocation in the class Dog and not in the class Animal.
Why is this? I want it to call askForLocation in the class Animal, so I was expecting not to see line 5 at all.
Line 14-17 in the output. I can't understand why the code executes tt all. I was expecting it to end at line 13.
Would be really nice if someone could explain this.
I can get around the problem by renaming the method askForLocation() in the class dog to for example askForLocation2(), but I want to know how it works.

Answer to question 1 : "this" refers to the current object being executed. In your case current object being executed is "Dog". Since Java uses dynamic binding for resolving overriding methods, so this.askForLocation(), will invoke the method of Dog class.
Answer to question 2 : you can understand this by creating a stack trace.
main(1) ->
Dog,askForLocation(2)->
Animal,askForLocation(3) ->
Dog,askForLocation(4)->
Animal,askForLocation(5)
After completing 5th one, control will go back to 4 one, will complete the remaining statements(statements after super.askForLocation(); ), call to 3rd one is already completed, then control will go back to 2 one executing the remaining statements(statements after super.askForLocation(); ), finally control will come back to main() where program will finish execution.

What you are seeing with the askForLocation method is called 'dynamic binding'. When you call a (non-private) instance method, then Java resolves the class of the instance at runtime, in this case Dog, and will always look for this method in that class first. Only if it doesn't find it there, it "goes up the inheritence ladder" (from point of view of your code), in this case to class Animal. But as you have overriden the method in class Dog, it will always execute the overriden version of the method from the Dog class, no matter from what class you call it. Note that this in class Animal refers to the instance in context, which is still a Dog.
I guess you could just put your code in the Animal class in a loop instead of doing recursive calls to the method. But there may be a better way to do it, my answer is mainly about explaining to you why your program behaves as it does.

On start of execution from here doggy.askForLocation(); you got Dog class function callled-
public void askForLocation() {
Scanner inFromConsole = new Scanner(System.in);
System.out.println("In dog");
String city;
super.askForLocation();
System.out.println("Back in dog");
System.out.println("City?");
city = inFromConsole.nextLine();
System.out.println("city: " + city);
}
Now when it came to super.askForLocation() it went to Animal class and from there you entered nothing so it called this.askForLocatioon(). Now this refers to the current object which is doggy of Dog class so again Dog's class function -askForLocation() called on line 5 . Now in animal class you enter the street and control passes back to the Dog class function and you run the rest of the code.
After this, the control passes to the first instance of askForLocation() function in the stack that could not complete because u called this.askForLocation().
And thats why you get the code repeated 14-17.
The subsequent function calls get stacked up in the stack.
A simple workaround could be like this:
public class Animal {
public void askForLocation() {
System.out.println("In animal");
System.out.println("Street?");
Scanner inFromConsole = new Scanner(System.in);
String street = inFromConsole.nextLine();
while (street.equals("")) {
System.out.println("Street?");
street = inFromConsole.nextLine();
}
else
System.out.println("Street: " + street);
}
}
}
There could be better workarounds too.

The recursive call in Animal#askForLocation calls askForLocation on this. It doesn't call Animal#askForLocation. It calls this.askForLocation, whatever that is. If this is a Dog, it calls Dog#askForLocation, because that's what would happen in any other code, whether its in another method in Animal, or outside these classes entirely. Imagine, e.g. doing Animal foo; if (bar) foo = this else foo = ...; foo.askForLocation();. You need to be specific that you want to call the code written in the Animal class. The easiest way is:
public class Animal {
private void askForLocationLoop() {
// ...
}
public void askForLocation() {
askForLocationLoop();
}
}
public class Dog extends Anumal {
#Override
public void askForLocation() {
// ...
}
}
private methods entirely bypass virtual dispatch; any recursive call in askForLocationLoop will always go back to it, even if a subclass declares another method with the same name, because it's a private method.
For your output, I'll show you the call stack for each line:
1: Dog#askForLocation
2-4: Dog#askForLocation > Animal#askForLocation
5: Dog#askForLocation > Animal#askForLocation > Dog#askForLocation
6-9: Dog#askForLocation > Animal#askForLocation > Dog#askForLocation > Animal#askForLocation
10-13: Dog#askForLocation > Animal#askForLocation > Dog#askForLocation
14-17: Dog#askForLocation.
There are two Dog#askForLocations in the stack. When the second one returns, the Animal#askForLocation above it also returns, so between 13 and 14 we go up two methods.
Now, for "fun"
// given f : (A -> B) -> (A -> B), calculate g : A -> B
// such that f(g) = g, making g the fixed point of f,
// and then call g on an A
static <A, B> B fix(Function<Function<A, B>, Function<A, B>> f, A a) {
return f.apply(a2 -> fix(f, a2)).apply(a);
}
public class Animal
public void askForLocation() {
Function<Function<Void, Void>, Function<Void, Void>> step = continu -> ign -> {
System.out.println("In animal");
System.out.println("Street?");
String street = new Scanner(System.in).nextLine();
if(street.equals(""))
return continu.apply(null);
else
System.out.println("Street: " + street);
return null;
};
fix(step, null);
// we write step in terms of open recursion; it gets an argument
// continu that it can call to "recurse" and fix feeds step to itself.
// that is; fix lets you write recursion indirectly.
}
}
Now you don't have to explicitly write a private method (but the compiler will end up doing so anyway by lifting the lambda).
Or you may just use a do-while loop:
public class Animal
public void askForLocation() {
String street;
do {
System.out.println("In animal");
System.out.println("Street?");
street = new Scanner(System.in).nextLine();
} while(street.equals(""));
System.out.println("Street: " + street);
}
}

Related

The relation between the declared type and created type

I have an question about the following code (Is this call dynamic binding?). I feel confused about 3 point.
First, what is the mean of the variable pq? Does pd still be the data type of P or be the Q?
Second, when I invoke the pq.m(pp) method, why the result become Q::P but not P::Q?
Finally, what is this mean ((P) qq).m(qq);? I hope somebody could solve my problem.
The result of the following code will be
P::Q, Q::P, Q::Q, R::P, Q::P, Q::Q, Q::Q
class Test {
public static void main(String[] args) {
P pp = new P();
Q qq = new Q();
R rr = new R();
P pq = qq;
pp.m(qq);
pq.m(pp);
pq.m(qq);
rr.m(pp);
qq.m(pq);
qq.m(qq);
((P) qq).m(qq);
}
}
class P {
public void m(P p){System.out.println("P::P"); }
public void m(Q p){System.out.println("P::Q"); }
public void m(R c){System.out.println("P::R"); }
}
class Q extends P {
public void m(P p){System.out.println("Q::P"); }
public void m(Q p){System.out.println("Q::Q"); }
public void m(R c){System.out.println("Q::R"); }
}
class R extends Q {
public void m(P p){System.out.println("R::P"); }
public void m(Q p){System.out.println("R::Q"); }
public void m(R c){System.out.println("R::R"); }
}
P pq = qq; means that pq is known to the rest of the program as a type P. But as the creator, you know it's really of type Q. So this means that when you call pq.m(), it's really calling the implementation from class Q.
It's called overriding a method. So when you call pq.m(pp), you are really calling:
public void m(P p){System.out.println("Q::P"); because that is the method from class Q.
If Q did not have a m(P) method, then it would automatically call the superclass method, the one from P.
((P) qq).m(qq); is the same as doing:
P pqq = (P)qq; // pqq is known as P type, but it's instance is still the original Q type
pqq.m(qq); // Again, since pqq is truly an instance of Q, it calls Q.m(Q)
You should really read about inheritance. This is a bigger subject than can be explained here.
All this being said, your example doesn't illustrate its power well. But for example, if class Q had an extra method, public void sayHello();, then
Q q = new Q();
P p = new Q();
q.sayHello(); // This would be legal
p.sayHello(); // This would be illegal because the compiler knows p as a declared instance of P, even though you know it's truly a Q.
((Q)p).sayHello(); // This would be legal because you told the compiler to look at p as an instance of Q. It's called a cast.
I hope this all helps. Be sure to go read up on object orientation.
Starting, I think you mean pq, not pd. Since Q extends P, Q is also a P type. It's like saying that an apple is a fruit. So you take the apple (Q) and says: It's a fruit (P). When you call the pq methods, they will call the methods from the Q class, since pq is still a Q object.
In the last part, when you do ((P) qq).m(qq);, is the same as doing the following:
P p = (P) qq;
q.m(qq);
So as said above, the code will still call the method from the Q class, printing "Q::Q"
Dynamic binding, and therefore polymorphism, only works for the object to the left of the dot in a method call (o.m(x) -- only for o). The arguments types are resolved statically, at compile time. Take a more well-known situation:
class A {
public boolean equals(A other) {
System.out.println("A.equals called"); return true;
}
}
A a1 = new A(), a2 = new A();
Object o = a1;
o.equals(a1); // doesn't print anything
a1.equals(o); // doesn't print anything
a1.equals(a2); // prints "A.equals called"
The point here is that class A doesn't override Object.equals(Object), but instead just adds another overloaded method A.equals(A) -- and that one gets called only when the argument is of a declared type A.

Java - Method declared but cannot reference it

I am kind of new to Java, although I've programmed in other procedural langauages for 25 years. So, I'm trying to teach myself Java. Trying to write some silly program consisting of two files: a Class called "Customer", and a main program called "Silly4".
I'm pretending to implement a credit card system for a bank type company (even though the majority of my experience was in defense contracting). I figure this would be a good teaching example for me.
Trying to build a credit card data structure called "Customer" such that (for the time being) it can accomodate 1000 customers. In the main program "Silly4", I instantiate this Customer class as "cust2", and then from there I attempt to work with "cust2". I try to retrieve customer number 5's (j=5) credit card balance. So far, so good.
Then from there I attempt to declare in the class Customer another method (for future use) which I arbitrarily call "bal44", and then I attempt to reference it in the main program Silly4 as " ball44(5541);".
So I compile class Customer, then compile program Silly4, and I'm getting a compile error "java:52: error: cannot find symbol" for the reference to method "bal44(5541)" in main program "Silly4". I'm confused. I've declared and successfully compiled the class Customer with "bal44" in there, but Java is telling me it can't find it. I'm confused.
Please excuse all the extraneous println's, I use them to see how the program is moving along.
Here is class Customer:
// Data Structure for credit card database
public class Customer {
private String name;
private int accountNo;
private double balance;
private boolean Overdue;
// Getters, setters, constructor...
public void setName( String new_name )
{ name = new_name; }
public void setAccount( int new_account )
{ accountNo = new_account; }
public void setBalance( double new_bal )
{ System.out.println( " Start proc setBalance ");
balance = new_bal;
System.out.println( " Finish proc setBalance ");
}
public double getBalance()
{ System.out.println( " Start proc getBalance ");
System.out.println( " proc getBalance , balance= " + balance + " end print");
return balance;
// how to specify which element of array[1000] ? balance I want ?
// System.out.println( " Finish proc getBalance ");
}
// Add new customer to credit card system
// (note - index in array Customer[i] is worry of main program
//
public void addCustomer( String name2, int account2, double bal2 )
{ name = name2;
accountNo = account2;
balance = bal2;
}
public void bal44 ( int account3 )
{ accountNo = account3; }
// Constructor
Customer ()
{ name = "John Smith";
accountNo = 1005;
balance = 125.43;
Overdue = false; }
// see page 1032 Liang for definition complex Object and get-Procs for it
}
Here is main program/class Silly4:
class Silly4
{
// Program for credit card database
public static void main(String[] args)
{
double bal2, bal3;
int i; // loop counter
int j;
bal2 = 151.47;
bal3 = 5.0; // just initialize
// And then you can create an array of it:
System.out.println("** Program Silly4 Running **");
Customer[] cust2 = new Customer[1000];
System.out.println("** Array cust2 instantiated **");
for(i=0; i<=999; ++i)
{
cust2[i] = new Customer();
}
System.out.println("** Array2 cust2 Obj initialized **");
// try to code this eventually - cust2.balance = 151.47 ;
//
j = 5; // customer no. 5
cust2[j].setBalance( bal2 );
bal3 = cust2[j].getBalance() ;
System.out.println("** Balance Customer " + j + " is " + bal3);
// Add a new customer
// comment out - addCustomer( "Steve Jones", 5541, 1.0 );
bal44( 5541 ); // test out declaring new method "bal44"
System.out.println("** End of Silly4 **");
}
}
You basically answered yourself in the first sentence of your query. Java is not a purely procedural language, it's an object-oriented language.
That means that when you declare methods, they are not just scoped functions. A method declared in a class is not similar to a function declared in an included file in C. It's something that can be only called from the scope of an object of the enclosing class. In other words, you don't have a function named bal44. You have a method bal44 of class Customer, which means that you need to ask an object fo class Customer to execute it for you, similar to how you call setBalance().
EDIT: As another comment mentions, what might be confusing you more is that whenever you use a method name without qualifiers, Java treats it as a shortcut of asking this (the current object) to execute the method, so technically, method(args) is a shortcut for this.method(args). Therefore, whenever you are within the scope of a single class, a class's methods will behave almost as traditional functions.
When you call
bal44( 5541 );
Without any object, Java assumes it as a "this" object and searches for that method in Silly4 not in Customer class. Call that method from Silly4 like you are calling other method of customer class.
e.g.
cust2[j]. bal44( 5541 ); or something like that.
Read more about "this" here https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
P.S. A bonus point to note here is that static method's like main method do not have this reference available to them. So, technically here it is searching for a class-level(static) method in Silly4 rather than instance method. :)
See, here is the problem : You are using the bal44(5541), but you made that method non static, meaning you need to make an object of your class (Customer) and then say for example
Customer customer = new Customer()
customer.bal(5541);
If you want to call that method without making an object of its class, simply put the keyword "static" in the method's header. public static void bal44(int num)
Further explanation : Since you are from a procedural language, recall the main difference is the usage of objects. An object is something that has several traits, or attributes, and actions or behaviors. For example a car, its attributes are its color, speed, etc. and its main action/behavior is drive. Attributes are variables, and Behaviors/Actions are methods. e.g.
car.drive();
car.setColor("red");
I hope that helped? If you don't understand you can PM me or respond here and I'll explain in further detail

logical error in this java code, how do i resolve this error?

public class DogOwner extends Dog {
public static void main(String[] args){
Dog dog1 = new Dog ();
Dog dog2 = new Dog();
Dog dog3 = new Dog();
dog1.setLegs(4);
dog1.setTail(true);
dog3.setFur(" furry fur");
System.out.println("this dog has"+ dog1.GetLeg()+"legs");
System.out.println("does this dog have a tail?"+ dog2.Gettail());
System.out.println("this dog has"+ dog3.GetFur());
}
}
}
}enter code here
enter code here
public class Dog {
/** variables**/
int Legs;
boolean tail;
String Fur;
/** returns the Legs variable (getter) **/
public int GetLeg(){
return Legs;
}
/** stores method variable Llgs within variable legs (setter) **/
public void setLegs(int legs){
this.Legs=legs;
}
/** returns the tail variable (getter) **/
public boolean Gettail(){
return tail;
}
/** stores method variable tail within variable tail (setter) **/
public void setTail(boolean tail){
this.tail=tail;
}
/**because the void does not work with String data type, the type String
* replaces void to make this code work (Hovercraft Full Of Eels, 2013)
* Hovercraft Full Of Eels.2013.why is this code not working in Java?.
* accessed from:http://stackoverflow.com/questions/20588830/why-is-this-code-not-working-in-java.
* stockoverflow.com. [accessed: 14/12/2013]**/
public String GetFur(){
return Fur;
}
/**stores for the method variable within the parameter variable Fur **/
public void setFur(String fur){
this.Fur=fur;
}
}
the output that i wanted was:
this dog has 4 legs,
Does this dog have a tail? True,
this dog has furry fur
the text true should not be text and it should execute what the boolean value is, in this case it should execute true without the use of quoatation mark (hope this makes sense).
im a beginner at Java and I can't seem to understand fully on how to code in java (or any programming language) using books. I require assistance from someone to fully understand coding. Also please explain how this code was resolved so I can understand the problem and how to resolve these types of problem in the future (hopefully).
thanks in advance.
You can't just put the object in the output string and expect it to know what you mean.
when you add a regular object to a string, it calls its toString() method, which you haven't defined and defaults to what looks like a bunch of grable...
Instead, you need to do something like System.out.println("this dog has"+ dog1.getLegs() +"legs"); and likewise on the others.
You don't seem to be calling the methods, just inserting the objects into the strings - this won't work in a sensible manner most of the time. Try calling the 'get' methods you've implemented.
"this dog has " + dog1.GetLegs() + " legs";
"does this dog have a tail? " + dog2.GetTail();
"this dog has " + dog3.GetFur() + " fur";
On the lines where you print the information you print the object instead of one of the properties for it. Change the first System.out.println to:
System.out.println("this dog has"+ dog1.GetLeg() +"legs");
I think you will figure out how to change the other rows :)

Head First Java example explanation needed

Hi! I'm reading Head First Java and i can't understand the behaviour of the following code:
public class Dog {
String name;
public static void main(String[] args) {
// make a Dog object and access it
Dog dog1 = new Dog();
dog1.bark();
dog1.name = "Bart";
// now make a Dog array
Dog[] myDogs = new Dog[3];
// and put some dogs in it
myDogs[0] = new Dog();
myDogs[1] = new Dog();
myDogs[2] = dog1;
// now acces the Dogs using the array references
myDogs[0].name = "Fred";
myDogs[1].name = "Marge";
// Hmmm... what is MyDogs[2] name?
System.out.print("last dog name is ");
System.out.println(myDogs[2].name);
// now loop through the array
// and tell all dogs to bark
int x = 0;
while (x < myDogs.length) {
myDogs[x].bark();
x = x + 1;
}
}
public void bark() {
System.out.println(name + " says Ruff!");
}
The output produced by this code is the following:
null says Ruff!
last dog name is Bart
Fred says Ruff!
Marge says Ruff!
Bart says Ruff!
I have a very hard time understanding this, IMO the code should run to somekind of infinite loop. From what i understand (and i've previously programmed in python): When the class is acticated, the main method gets called, and then inside the main method, two more classes of the same type are created. (Now here comes the incomprehensible part -->) When the new class is created, inside it's main method, 2 more classes are created and so on .. How can it be that it produces the output shown above, when it creates an infinte number of classes, so the code should actually never finish running.
Thank you!
The code you've posted just instantiates a total of 3 instances of the Dog class. The myDogs array has 3 elements, so the while loop is guaranteed to terminate.
What's not clear?
The main method is called only when executing the program. Your program could have been written like this (more clear for a Java beginner, I think):
class Dog {
String name;
public void bark() {
System.out.println(name + " says Ruff!");
}
}
public class MyDogTest {
public static void main(String[] args) {
// make a Dog object and access it
Dog dog1 = new Dog();
dog1.bark();
dog1.name = "Bart";
// now make a Dog array
Dog[] myDogs = new Dog[3];
// and put some dogs in it
myDogs[0] = new Dog();
myDogs[1] = new Dog();
myDogs[2] = dog1;
// now acces the Dogs using the array references
myDogs[0].name = "Fred";
myDogs[1].name = "Marge";
// Hmmm... what is MyDogs[2] name?
System.out.print("last dog name is ");
System.out.println(myDogs[2].name);
// now loop through the array
// and tell all dogs to bark
int x = 0;
while (x < myDogs.length) {
myDogs[x].bark();
x = x + 1;
}
}
}
If you put the two classes (Dog and MyDogTest) inside the same .java file, please note that only MyDogTest should be declared as public, otherwise the program won't compile.
You're misunderstanding the main() method.
Java calls the main() method when you start executing a program.
Instantiating a class does not run the main() method; it will just run the class's constructor.
Instantiating a class will call the constructor of the class. You didn't define one, so your constructor is actually one without parameters and without body, like this:
public Dog () {
}
Of course, this constructor will never cause an infinite loop.
The main method is the one called when starting your program and thus called exactly once.
Notice the static keyword in the main() method declaration. It means that the method is always accessible, unrelated to a specific class instance. (Since you come from Python world, you are welcome to read a bit about the field modifiers).
You can in a way observe it as "an external" method (meaning you can always access it externally and execute it with Dog.main(your string args)), that is not "aware" of the class existence. Also notice that multiple classes that you use can have main method, in which case you should decide which one is the really the main one, by declaring it in the manifest file, but this is a bit advanced topic, that is left for your further research.
And of course, as the others already explained, main method is a specific method that the JVM runs once, in the moment you execute your program.

Recursive java method, get mother, grand mother, great grand mother and so on

I have a list Dogs in a text file with the following format:
id:fatherid:motherid:born:owner:breed
ex:
3:2:1:2000:Scotty:Peter:dachs
I then populate an array list with objects of dog. I Need a method that returns all the mothers for a dog with a given id. I already have methods for: getMother, getDog, getChildren, getParents, existDog. getDog and getMother returns a Dog, getChildren and getParents returns a String. Now i need a method that gives me the mother, grand mother, great grand mother and so on. I do not know how to make this method. This code gives me the mother and grand mother of a dog:
public String getMotherTree(int id) {
String output = "";
if (existDog(id)) {
Dog mother = GetMother(id);
output += mother.toString();
int morId = mother.getId();
Dog grandMother= GetMother(motherId);
output += grandMother.toString;
return output;
}
output = "The dog with that id do not exist!";
return output;
}
I think that what i need is a recursive method, but i do not know how to do this.
Basically, you'd create a method that calls itself with another parameter unless some condition is met.
In your case, you might use getMotherTree() (or some adjusted method):
public String getMotherTree(int id) {
String output = "";
if (existDog(id)) {
Dog mother = GetMother(id);
output += mother.toString();
int morId = mother.getId();
return output + ", " + getMotherTree(morId); //recursion
}
//return an empty string if the dog doesn't exist
//this basically ends the recursion
return output;
}
As BalusC pointed out recursion is not necessary here, so please view that as a learning exercise only.
You don't need recursion for this: you could replace your IF with a WHILE, and after adding the mother to the String, replace id with the id of the mother. (If you still want a message if the dog doesn't exist, just check if output is blank or not before returning.)
Note that you have a logic problem (which what I just described doesn't solve): just because a dog exists doesn't mean it has a mother (or your loop/recursion would never end!), so calls to any method of this missing mother should fail.
It can be done recursively (which is computationally expensive but perhaps simpler code to understand) or can be done iteratively. Here's an iterative solution:
public String getMotherTree(int id) {
if (!existDog(id)) {
return "The dog with that id do not exist!";
}
StringBuilder output = new StringBuilder();
for (Dog mother = GetMother(id); mother != null; mother = mother.getMother()) {
if (output.length() > 0) {
output.append(", ");
}
output.append(mother.toString());
}
return output.toString();
}
This assumes that aDog.getMother() returns null if aDog has no mother in the data base.

Resources