Exercise on method call in class hierarchy - java

I'm trying to solve a problem about method calls in Java that seems really strange, I hope someone can help about it.
Here it is the code of the three classes, A is the top class with C inheriting from A and D inheriting from C.
class A {
int f(double x) {
return 1;
}
int f(boolean x) {
return 2;
}
}
class C extends A {
int f(double x) {
return 3;
}
int f(int x) {
return 4;
}
}
class D extends C {
int f(double x) {
return 5;
}
int f(int x) {
return 6;
}
}
public class test {
public static void main(String[] args) {
C b = new D();
A d = new D();
System.out.println(b.f(33));
System.out.println(d.f(33));
}
}
When I call method of object b with an int I get 6, which means that the method f(int x) from class D is called. But when I call the same method on object d I get 5, which means that the method f(double x) from class D is called. Why does it behave like that? Why an integer is considered an integer in one case and a double in the other? It is something related to how I declared the two objects but I can't get it.

The difference is in the type of the objects. b's reference is of type C and d's reference is of type A. In cases of inheritance, the JVM binds the methods at run-time, meaning that you can only call methods of the reference type, but the overridden method is the one that will run.
When you call the function on d, the JVM automatically casts to a double because A has no corresponding method for an int argument. Then, the method trickles down to D because the object is an instance of D, but it still trickles down as a double.

Related

Not able to create an object of subclass in separate class in eclipse [duplicate]

This question already has answers here:
What causes error "No enclosing instance of type Foo is accessible" and how do I fix it?
(11 answers)
Closed 5 years ago.
I'm learning inheritance in java. While writing small code where I'm learning we cannot access private members of superclass in subclass.
Here is my code:
class A {
int i;
private int j;
void setij(int x, int y) {
i = x;
j = y;
}
class B extends A {
int b;
void sum() {
b = i + j;
}
}
When I create a new class in eclipse, am not able to create an object of sublcass B in class A.
class mainclass{
public static void main(String args[]){
B object = new B(); ----error
}
}
}
Error says class B needs to be created.
May I know why is happening ..? Its happening not a problem but I want to solve and understand the logic why it was happened.
Thanks
That's because class B is present inside class A, it needs to be created outside of A, e.g.:
class A {
int i;
private int j;
void setij(int x, int y) {
i = x;
j = y;
}
}
class B extends A {
int b;
void sum() {
b = i + j;
}
}
With this code, class B (and A) will be accessible from all the classes from inside the package. If you want these classes to be accessible from outside the current package then you need to create these classes in separate files and mark them as public.
Here's more on access modifiers for classes.
Upate
If you want to define class B as an inner class in A then you will need the instance of enclosing class (A in our case) to access B, e.g.:
class A {
int i;
private int j;
void setij(int x, int y) {
i = x;
j = y;
}
class B extends A {
int b;
void sum() {
b = i + j;
}
}
}
Now, to instantiate B, you need to do the following:
A a = new A();
B b = a.new B();
And of course, same rules as access modifier will apply to inner class instance (except the fact that inner class will be able to access private members of enclosing class),
This is because an instance of class B must relate to an instance of class A. So you must first create an instance of class A, then the instance of class B:
A a = new A();
a.setij(1,2);
B b = a.new B();
b.setij(3,4);
b.sum();
System.out.println(b.b);
(the result is 5 in case you were wondering)

Scala -> Java , Pass function as a parameter to another function

I am exploring both scala and Java 1.8 but unable to find equivalent code in with java 1.8 lambda expressions.
Scala code:
object Ex1 extends App {
def single(x:Int):Int =x
def square(x:Int):Int = x * x
def cube(x:Int):Int = x*x*x
def sum(f:Int=>Int,a:Int,b:Int):Int=if (a>b) 0 else f(a) + sum(f,a+1,b)
def sumOfIntegers(a:Int,b:Int)=sum(single,a,b)
def sumOfSquares(a:Int,b:Int)=sum(square,a,b);
def sumOfCubes(a:Int,b:Int)=sum(cube,a,b);
println(sumOfIntegers(1,4));
println(sumOfSquares(1,4));
println(sumOfCubes(1,4));
}
output:
10
30
100
java:
public class Test1{
public int single(int x){
return x;
}
public int square(int x){
return x * x;
}
public int cube(int x){
return x * x * x;
}
// what's next? How to implement sum() method as shown in Scala?
// Stuck in definition of this method, Stirng s should be function type.
public int sum( Sring s , int a, int b){
// what will go here?
}
public int sumOfIntegers(int a, int b){
return sum("single<Function> how to pass?",a,b);
}
public int sumOfSquares(int a, int b){
return sum("square<Function> how to pass?",a,b);
}
public int sumOfCubes(int a, int b){
return sum("cube<Function> how to pass?",a.b);
}
}
Is it possible to achieve the same with JDK 1.8?
You are going to need to define the methods that you are going to use. The only one that comes with Java is the Function<X,Y> which (with Integer) can be used for single, square and cube and BiFunction<T,Y, R> which can be used for the three sumOfs.
interface Sum {
Integer apply(Function<Integer, Integer> func, int start, int end);
}
The single, square and cube could be either methods in the class (see cube or inline (see the other two). They are Fuctions. This function can then be passed to other methods and called with variableName.apply.
class Test
{
private static Integer sum(Function<Integer, Integer> func, int a, int b) {
if (a>b)
return 0;
else return func.apply(a) + sum(func,a+1,b);
}
private static Integer cube(Integer a) {
return a * a * a;
}
public static void main (String[] args) throws java.lang.Exception
{
Function<Integer,Integer> single = a -> a;
Function<Integer,Integer> square = a -> a * a;
Function<Integer,Integer> cube = Test::cube;
// You can not do the sum in-line without pain due to its recursive nature.
Sum sum = Test::sum;
BiFunction<Integer, Integer, Integer> sumOfIntegers = (a, b) -> sum.apply(single, a, b);
BiFunction<Integer, Integer, Integer> sumOfSquares = (a, b) -> sum(square, a, b); // You could just use the static method directly.
BiFunction<Integer, Integer, Integer> sumOfCubes = (a, b) -> sum(cube, a, b);
System.out.println(sumOfIntegers.apply(1,4));
System.out.println(sumOfSquares.apply(1,4));
System.out.println(sumOfCubes.apply(1,4));
}
}
Yes, it is possible:
public Integer sumSingle(Integer a) { return a; }
public int sum(Function<Integer, Integer> f, int a, int b)
{
... : f.apply(a+1); // or whatever
}
public int sumOfIntegers(int a, int b)
{
return sum(Test1::single, a, b);
}
The construct Class::method creates a Function object from the method. Or if you don't need to reuse it, you can directly pass an argument instead: (Integer a) -> a*a* ...
Function<Integer, Integer> single = x -> x;
Function<Integer, Integer> square = x -> x*x;
public int sum( Function<Integer, Integer> s , int a, int b){
if (a>b){
return 0;
} else {
s.apply(a) + sum(s,a+1,b)
}
}
In Java 8 you can use any functional interface, i.e. an interface with exactly one non-static method without a default implementation, in place of Scala's Function<N> types. There are quite a few such interfaces in the java.util.function package, for single-argument and two-argument functions; in particular for functions which take and return int you should use IntUnaryOperator, already mentioned in other people's comments. If you have more than two arguments, or two arguments of different types, define your own interface with one method. E.g. for functions of 3 arguments which take int, long and long and return a non-primitive:
interface Fun3ILLO<T> {
public T apply(int arg1, long arg2, long arg3);
}
(obviously you can choose the interface and method name you want).

java code compilation heritage extends

This code has a compilation problem. How do I get a.f()?
class A {
int i = 1;
int f() {
return i;
}
static char g() {
return 'A';
}
}
class B extends A {
int i = 2;
int f() {
return -i;
}
static char g() {
return 'B';
}
}
class Test {
public static void main(String args[]) {
B b = new B();
System.out.println(b.i);
System.out.println(b.f());
System.out.println(b.g());
System.out.println(B.g());
A a = b;
System.out.println(a.i);
System.out.println(a.f());
System.out.println(a.g());
System.out.println(A.g());
}
}
and this is the result
2
-2
B
B
1
-2
A
A
You've not specified any access modifiers for your class members, so it has default or package level access only and is not available to sub classes
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
See here for more details
If you change the signature of f() to protected int f() then it should work
Of course you have the same issue with the other members of the class so it's up to you how you control this
Overriding is just for instance methods, not for variables. So, when you get the variable i from instance of the class A, you get the value from this Class. The same thing with the instance of class B.
But you can reinitialize the value of i in constructor, for example:
class B extends A {
public B() {
i=2;
}
int f() {
return -i;
}
static char g() {
return 'B';
}

Defining a comparator for a quadratic function object

This is my assignment,
a) Write a quadraticFunction that represents a quadratic ax^2 + bx + c with int coeffients a, b, c. Provide a constructor with 3 int parameters for a, b, c. Provide a method double valueAt(double x) returns the value of this quadratic function at x. Also provide a toString method.
b) override the equals method quadraticmethod class. two quadraticfunction should be considered equal if their respective coeffiecients are equal
c) Make the function objects comparable. The compareTo should first compare 1 if equal compare b if equal compare c
d) Define a comparator class for comparing two QuadraticFunction objects. Provide two constructors: a no-argss constructor and a constructor that takes 1 double parameter. When a comparator is created by the no-args constructor, it should compare two quadraticFunction based on their values at x = 0; when a comparator is created by the constructor with a parameter x, it should compare quadraticFunction based on their values at x
Here's my code
I need help with part D, I don't know how to do some of it
public class Ex4
{
int a;
int b;
int c;
public Ex4(int x, int y, int z)
{
a = x; b=y; c=z;
}
public String toString()
{
String X="";
X= X+a+"x^2"+b+"x"+ "+" + c;
return X;
}
public double valueAt(double x)
{
return (a*x*x+b*x+c);
}
//////// Part B
public boolean equals( Ex4 qf )
{
return(this.a==qf.a && this.b==qf.b && this.c==qf.c);
}
/////Part c
// public int compareTo(Ex4 other)
// {
// if (a.equals(other.a))
// {
// if (b.equals(other.b))
// return c.compareTo(other.c);
// return b.comapreTo(other.b);
// }
// return a.compareTo(other.a);
// }
public int compareTo(Ex4 other)
{
if (a > other.a)
return 1;
else if (a < other.a)
return -1;
else if (b > other.b)
return 1;
else if (b < other.b)
return -1;
else if (c > other.c)
return 1;
else if (c < other.c)
return -1;
else
return 0;
}
////Part d
public static void main(String[] args)
{
System.out.println(new Ex3(1, -5, 6));
}
}
Also in the uncomment the area of code under part c, it says int cannot be dereferenced on line 29, 31, 32,33, and 35
Thanks for the help
You can't call methods on primitives, plain and simple.
A better option is to use Integer's static method, Integer.compare(int a, int b) to compare two ints.
First, writing a custom Comparator isn't too terribly difficult; you need to understand the basic structure of one.
Here's the idea: it reads kind of like you're writing a Comparable entity.
class CustomComparator implements Comparator<Ex4> {
#Override
public int compare(Ex4 left, Ex4 right) {
// Compare the entities as specified by the assignment
}
}
Then, you need to accept that as a constructor argument. That, I leave as an exercise to the reader.
Now, to the syntax issue: you're treating primitive int as an Integer, which does have an equals method on it. Primitives aren't objects, hence they can't be dereferenced. You'll want to use the normal equivalence operators (==, >, <) in this situation. You have this already solved in your second-defined compareTo method.
EDIT: After re-reading your requirements, I'm starting to think that your primitive fields are not the right way to go. You should:
Change your fields from int to Integer
Implement Comparable<Ex4> on your entity class
Rely on the default behavior of compareTo() for Integer; that is, your commented code should "just work" (save for the misspell when comparing against C)
Move the secondary compareTo to its own Comparator entity, as described above.
Try this
import java.util.Comparator;
public class Ex4Comparator implements Comparator<Ex4> {
private double x = 0.0;
public Ex4Comparator() {
}
public Ex4Comparator(double x) {
this.x = x;
}
#Override
public int compare(Ex4 o1, Ex4 o2) {
return Double.compare(o1.valueAt(x), o2.valueAt(x));
}
}
Also your equals method doesn't override Object's equals method. You may want to change it to something like
#Override
public boolean equals(Object o) {
if (o instanceof Ex4) {
Ex4 other = (Ex4)o;
return (a == other.a && b == other.b && c == other.c);
}
return false;
}

Have I invoked correctly?

I have been given a piece of code (the class QuestionTwo).
I am asked to state the values of a, b, and c after method mQ2 is invoked on a newly created object of class Q2.
My main.java file
package openuniversity;
public class Main
{
public static void main(String[] args)
{
QuestionTwo qt = new QuestionTwo();
qt.mQ2();
}
}
My QuestionTwo.java class file:
package openuniversity;
public class QuestionTwo
{
int a;
int b = 1;
public void mQ2()
{
{
int c;
int a = 2;
c = a;
}
{
int c;
int a;
c = 3;
a = 4;
}
a++;
}
}
I arrived at:
a: 1
b: 1
c: 3
Note I can also select 'undefined' as an answer?
So would it be 1, 1, undefined as c does not exist outside of the codeblock?
The question:
Study the following code and then select the options from the drop-down lists below that are correct about the values of a, b and c after the method mQ2 is invoked once on a newly created object of class Q2. Note that the answers you choose for a, b and c may or may not be different from each other.
public class Q2
{
int a;
int b = 1;
public void mQ2()
{
{
int c;
int a = 2;
c = a;
}
{
int c;
int a;
c = 3;
a = 4;
System.out.println("c: " + c); //correct place?
}
a++;
}
System.out.println("a: " + a + "b: " + b); // correct place?
}
Since this is homework, I'll restrict my answer to a couple of pointers.
You can verify your solution by printing out the variables after calling mQ2() (hint: you could use System.println() for that).
This is either a trick question or is partially ill-defined (hint: think about which a, b and especially c you're being asked about).
I'd suggest you first print out all the values using System.out.println() after calling mQ2, then step through the code in your mind to try to work out why the values are what they are. Remember that any variable declared is only visible within the scope ({...}s for simplicity), but these variables can have the same name as other variables so they might look like the same even if they're not.
I'd like to particularly point out that c does not exist outside that method.

Categories

Resources