Which overridden methods are invoked? - java

I am having hard time to understand the solution of the given question. I can't understand at each step which of the class' methods are invoked.
I tried to make a list for what are a,b,c declared types and actual types then try to chose overridden or overloaded methods but it is complex.
class Upper {
private int i;
private String name;
public Upper(int i) {
name = "Upper";
this.i = i;
}
public void set(Upper n) {
i = n.show();
}
public int show() {
return i;
}
}
class Middle extends Upper {
private int j;
private String name;
public Middle(int i) {
super(i + 1);
name = "Middle";
this.j = i;
}
public void set(Upper n) {
j = n.show();
}
public int show() {
return j;
}
}
class Lower extends Middle {
private int i;
private String name;
public Lower(int i) {
super(i + 1);
name = "Lower";
this.i = i;
}
public void set(Lower n) {
i = n.show();
}
public int show() {
return i;
}
}
class Tester {
public static void main(String[] args) {
Lower a = new Lower(1);
Middle b = a;
Upper c = new Middle(5);
a.set(c);
b.set(a);
c.set(b);
System.out.println(a.show());
System.out.println(b.show());
System.out.println(c.show());
}
}
What is printed as a result of System.out.println(a.show()); after the set commands? Answer is 1
What is printed as a result of System.out.println(b.show()); after the set commands? Answer is 1
What is printed as a result of System.out.println(c.show()); after the set commands? Answer is 1
I don't get why the answers of all these are 1. Also I can't tell which class' overridden or overloaded methods that "a.set(c); b.set(a); c.set(b);" uses. A detailed explanation would be really helpful.

a.set(c) uses the set-method from Middle, as that overrides the one from Upper and the (overloaded) set from Lower is not applicable because c is not an instance of Lower.
Therfore j is set to c.show() which returns c's attribute j, so it will be set to 5. Consequently the (Lower-)attribute i of a is never touched and remains at 1 when it is shown and printed.
Try to resolve the others yourself.

Related

Cannot pass random enum value to function in Java

Cheers, I am pretty new to java and I and I have ran across a problem
I have three classes, all inheriting things between them. Starting I have a class A:
public class A{
private int index;
public A(int index) {
System.out.println("Creating an instance of A");
this.index = index;
}
}
then I have a sublass of A, class M which has a enum inside as:
public class M extends A{
public enum Letter {
A,B,C;
}
private Letter letter;
public M(int index, Letter aLetter) {
super(index);
System.out.println("Creating an instance of M");
this.letter = aLetter;
}
}
and finally a last class P , subclass of M:
public class P extends M {
private T t;
public enum T{
o,
a,
t
}
public P(int index, Letter aLetter, T aT) {
super(index,aLetter);
System.out.println("Creating an instance of P");
this.t = aT;
}
}
What I want to do is create e.g. 3 objects of the class P, and pass on to them RANDOMLY a value of each of these enums. I thought of creating a function in the main class which would be kind of like:
Letter getRandLetter() {
Random rand = new Rand();
int pick = rand.nextInt(M.Letter.values().length);
if (pick == 0) {
return Letter.A;
} else if (pick == 1) {
return Letter.B;
} else {
return Letter.C;
}
}
my main looks like this:
int N = 3;
M[] new_m = new M[N]
for(int i = 0; i < N; i++) {
new_m[i] = new P(i, getRandLetter(), getRandT());
}
however I get this error: Cannot make a static reference to the non-static method . What Can I do to achieve what I want?
The error is telling what to do:
Cannot make a static reference to the non-static method
Your main method is static, and the methods called from it should be static as well. So your getRandLetter() and getRandT() methods should be static.
getRandLetter() should look like this:
static Letter getRandLetter() {
Random rand = new Rand();
int pick = rand.nextInt(M.Letter.values().length);
if (pick == 0) {
return Letter.A;
} else if (pick == 1) {
return Letter.B;
} else {
return Letter.C;
}
}
And getRandT() should be static as well.

Polymorphic Misunderstand

When i call s1.dub(7) or s2.dub(7) it doesn't work
,but calling it with a string like s2.dub("9") works and prints the doubled string
Could any one tell me why?
Here's the code
interface Inter {
int number();
}
abstract class Abs {
static int foo = 12;
int number() { return 5; }
abstract int ace();
}
final class Sub extends Super {
Sub(int bar) { foo = bar; }
public int number() { return 10; }
int ace() { return 13; }
int dub(int i) { return 2 * i; }
}
public class Super extends Abs implements Inter {
public int number() { return 11; }
public static void main(String args[]) {
Super s1 = new Super();
Super s2 = new Sub(16);
//System.out.println(s1.dub(7)); //doesn't work
//System.out.println(s2.dub(7)); //doesn't work
//System.out.println(s1.dub("7")); //works giving 77
//System.out.println(s2.dub("7")); //works giving 77
}
int twice(int x) { return 2 * x; }
public int thrice(int x) { return 3 * x; }
int ace() { return 1; }
String dub(String s) { return s + s; }
}
Very easy.. you class Super defines a method:
String dub(String s) { return s + s; }
in your main method you instantiate Super:
Super s1 = new Super(); // this has a dub( String ) method
then you try to call this method (dub) passing a integer, instead of a string:
System.out.println(s1.dub(7)); // s1.dub(...) takes a String, not a number
EDIT: This code should not compile, or run, because you are assigning both instances to the super class Super (which does not define a dub(int) method).
Not sure how you are getting exceptions?
Thank you #Jean-FrançoisSavard - I totally missed that!
EDIT2: The original question was modified and no longer indicates that an exception is thrown, which makes sense as the code should not compile at all.
EDIT3: (last one, due to original question changing)
System.out.println(s1.dub(7)); //- this will never work unless you change your class' definition
System.out.println(s2.dub(7)); //- will work if you also change the following line:
from:
Super s2 = new Sub(16);
to:
Sub s2 = new Sub(16);

Error : Main method not found in java class

I am new to concepts of java. while preparing my first program of classes with objects i encountered a problem. here is the code and the error..please resolve..
PROGRAM:
class Fact
{
private int i;
private int n;
private int fact;
public Fact()
{ fact=1;
i=1;
}
public Fact( int x)
{ n=x; }
public void getAnswer()
{
while(i<=n)
{fact=fact*i;
i++;}
System.out.println(fact);
}
}
class FactMain
{
public static void main(String dt[])
{
Fact obj= new Fact(6);
obj.getAnswer();
}
}
ERROR:
Main method not found in class Fact, please define the main method as:
public static void main(String[] args)
just change your Parameterized constructor to this
public Fact(int x) {
fact = 1;
i = 1;
n = x;
}
because you declare factorial in default constructor and you are not calling it. So, 0 is assigned to factorial and then you r trying to multiply it. Which makes no sense.
Rename the class file name Fact.java to FactMain.java.
private int fact;
public Fact()
{ fact=1;
i=1;
}
public Fact( int x)
{ n=x; }
Note, your default constructor set fact but constructor Fact( int x) set n. Hence fact is 0. So your output is 0 too.
Solution:
public Fact(int x) {
fact = 1;
i = 1;
n = x;
}
Or,
public Fact(int x) {
this(); // default constructor
n = x;
}
Here is the complete solution:
Create a single class file named FactMain.java, then paste the following code:
class Fact {
private int i;
private int n;
private int fact;
public Fact() {
fact = 1;
i = 1;
}
public Fact(int x) {
this();
n = x;
}
public void getAnswer() {
while (i <= n) {
fact = fact * i;
i++;
}
System.out.println(fact);
}
}
class FactMain {
public static void main(String[] dt) {
Fact obj = new Fact(6);
obj.getAnswer();
}
}
Your main method is in FactMain.java, but you are saving a file as Fact.java.
You will need to save the file as FactMain.java as JVM expects main to be in the same class as the name of .java file.
You have saved your file as Fact.java. So java is trying to find the main class in Fact. Save your file as FactMain.java It should work.
You have defined your main class in FactMain and most probably after compilation while running you're trying to execute
java Fact
And hence you got the error because there is no main method in Fact class.
Once you compile the .java file you will get two class files Fact.class and FactMain.class so you should execute
java FactMain
Move the FactMain class to FactMain.java
FactMain.java
public class FactMain
{
public static void main(String dt[])
{
Fact obj= new Fact(6);
obj.getAnswer();
}
}
Allow the Fact class to remain in the Fact.java file
Fact.java
public class Fact {
private int i;
private int n;
private int fact;
public Fact() {
fact = 1;
i = 1;
}
public Fact(int x) {
this();
n = x;
}
public void getAnswer() {
while (i <= n) {
fact = fact * i;
i++;
}
System.out.println(fact);
}
}
Compile the classes...
javac {package path}\FactMain.java
Run the main class
java {package path}.FactMain

DRY maxima tracking

Suppose I am importing table entries, where a single entry can be stored in a class:
class Foo {
int i1;
int i2;
double d1;
}
After the import is complete, I will need to have access to the imported values themselves, as well as to their normalized versions. So far, I have implemented this functionality as follows:
class FooWithMaxTracking {
private int i1;
private static int i1_max=0;
public void setI1(int value){
this.i1 = value;
if (value > i1_max) { i1_max = value; }}
public int getI1(){
return i1;}
public double normI1(){
return i1/((double)i1_max);}
private int i2;
private static int i2_max=0;
public void setI2(int value){ <code identical to written above> }
public int getI2(){ ... }
public double normI2(){ ... }
// and another set of similar 2 variables & 3 functions for 'double d1'
}
In this implementation I strongly dislike the fact that I had to write the same code many times (only three in this example, but about ten times in the real project). Is there any way to make the code more DRY ("don't repeat yourself")?
If you do not mind a slight loss of performance, you can put all the maxima in a static Map, define a class that holds a getter, a setter, and a norm methods, and replace the individual variables with instances of that class:
private static Map<String,Object> max = new HashMap<String,Object>();
private static class IntMaxTrack {
private final String key;
private int value;
public IntMaxTrack(String k, int v) {
key = k;
value = v;
max.put(key, value);
}
public int get() { return value; }
public void set(int v) {
int m = ((Integer)max.get(key)).intValue();
value = v;
if (value > m) {
max.put(key, value);
}
}
public double norm() {
int m = ((Integer)max.get(key)).intValue();
return val / ((double)m);
}
}
Make a similar class for double, i.e. DblMaxTrack Now you can replace primitives with instances of these classes, and call their get, set, and norm from the corresponding methods of your class.
What about defining one class with the necessary code, like:
public class Bar {
private int i1;
private static int i1_max = 0;
public void setI1(int value) {
// ...
}
public int getI1() {
// ...
}
public double normI1() {
// ...
}
}
And using it sevearl times, like:
class FooWithMaxTracking {
one = new Bar();
two = new Bar();
three = new BarForDouble();
}

Java 'this' keyword

I'm just beginning in programming and I'd like to make exercise from a book, but I can't. That's my problem:
public class increment {
int increment() {
return this + 1; // aka this++
}
public static void main(String[] args) {
int a = 0;
System.out.println(a.increment());
}
}
As you for sure guessed already, that it doesn't works, I want to ask you how to get outputed integer a incremented by one, but using keyword 'this'.
Regards and sorry for stupid questions.
It is strange to name a class like a method.
I guess you wanted this:
public class Counter {
int val;
public Counter (int start) {
val = start;
}
public void increment() {
val ++;
}
public String toString () {
return Integer.toString (val);
}
public static void main(String[] args) {
Counter counter = new Counter (0);
counter.increment ();
System.out.println(counter.toString ());
}
}
this is an object (the current object). You cannot "increment" it.
A way to do it is:
public class Increment {
int a = 0;
int increment() {
return a + 1;
// or: return this.a + 1;
// or: a++; return a; if you want a to be incremented from now on
}
public static void main(String[] args) {
Increment inc = new Increment();
System.out.println(inc.increment());
}
}
The this keyword in Java refers to the current scope's object instance. I don't think it's what you're looking for in this case.
In your example, a isn't an object of the class increment, it is a primitive int. In order to use the .increment() function you defined, it would have to be an object of type increment.
One option that may be what you're looking for would be the following.
public class Increment { //Java likes capitalized class names
private int myInt;
public Increment(int a) { //constructor
myInt = a;
}
public int increment() {
return ++myInt;
}
public static void main(String[] args) {
Increment a = new Increment(0);
System.out.println(a.increment());
}
}
In this example, we make a new class of type increment, which internally contains an integer. Its increment method increments that internal integer, and then returns the number.
you are using operator + for your current object (this). Operator overloading is not supported in java.
Something like this will work:
class MyInteger {
private int internal;
public MyInteger( int value ){
this.internal = value;
}
public int incerment(){
return ++this.internal;
}
}
public class Increment {
public static void main(String[] args) {
MyInteger a = new MyInteger(0);
System.out.println(a.increment());
}
}
You see, you can only implement methods for your own classes, not for existing classes, or for primitives like int.
i don't think you can use this to return the value, except if you're making a new class like this:
class Increment1
{
private int a;
public int increment2(int a)
{
this.a=a;
return this.a + 1;
}
}
public class Increment
{
static Increment1 b = new Increment1();
public static void main(String[] args)
{
int a = 0;
System.out.println(b.increment2(a));
}
}
You cannot increment a class like this.
You have to use a member variable that you can increment.
public class Test {
private int var;
public Test(int i) {
this.var = i;
}
int increment() {
this.var++;
}
}
public static void main(String[] args) {
Test t = new Test(0);
System.out.println(t.increment());
}
This refers to the current instance of the class, not a particular member.
You want to increment a property (I'm guessing of type long or int), and not the instance of your increment class (should be Increment, by the way).
Something like this would work:
public class increment {
private int innerValue = 0;
int increment() {
innerValue+=1
return innerValue; // aka this++
}
public static void main(String[] args) {
increment a = new increment()
System.out.println(a.increment());
}
}

Categories

Resources