I have a Java assessment that gets marked by a robot. Whenever I upload my assignment it shows a screen like this.
A good object-oriented design places each method into the most appropriate
class. The most appropriate class for a method should be the same class as
the data fields that that method needs to access. If you don't place a method
into the right class, then this will most likely increase the amount of
communication that is required between your classes.
The score below measures the amount of communication between your classes. A
lower score is better.
19 method invocations between classes
7 arguments passed between classes
15 results returned between classes
Amount of communication = invocations + 2*inputs + 2*outputs = 63
Now what exactly does "method invocations between classes", "arguments passed between classes" and "results returned between classes" mean?
Method invocations between classes
As your class contains their own methods if you want to call the method from another class you have to use an instance of this class.
For example :
class A{
public void methodA(){
}
}
class B{
public void methodB(){
}
}
If I want to call methodA() from the class B I must use this:
public void methodB(){
A a = new A();
a.methodA(); // method invocation between classes
}
Argument passed between classes
This time methodA() will need an argument, and B as a field which could be used as argument.
class A{
public void methodA(int argument){
}
}
class B{
private int fieldB = 42;
public void methodB(){
}
}
To call methodA() from B you will pass an argument from a class to another.
public void methodB(){
A a= new A();
a.methodA(fieldB); //Argument passed between classes
}
Results returned between classes
And now methodA() returns a result this is the code.
class A{
public int methodA(){
return 42;
}
}
class B{
private int fieldB;
public void methodB(){
}
}
To use/handle the returned value of the methodA() from the class B you'll have to do this:
public void methodB(){
A a= new A();
fieldB = a.methodA(); //Result returned between classes
}
I'd have to say:
method invocations between classes
Suppose you have classes X and Y. This would be any time class X calls some method on class Y.
e.g.,
class Y
{
public void foo() { }
}
class X
{
public void someMethod()
{
Y y = new Y();
y.foo();
}
}
arguments passed between classes
Could possibly mean one of two things.
Either you are accessing a field of another class directly.
class Y
{
public int number;
}
class X
{
public void someMethod()
{
Y y = new Y();
int yNum = y.number;
}
}
Or a method was called where arguments are supplied. (most likely case)
class Y
{
public void foo(int arg) { }
}
class X
{
public void someMethod()
{
Y y = new Y();
y.foo(56);
}
}
results returned between classes
Received a value from a method of another class that returned a value. e.g., getters or other methods.
class Y
{
public int foo() { return 42; }
private int number;
public int getNumber() { return number; }
}
class X
{
public void someMethod()
{
Y y = new Y();
int yFoo = y.foo();
int yNumber = y.getNumber();
}
}
Related
This question already has answers here:
Is there a way to override class variables in Java?
(17 answers)
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I am not able to understand the following output.
I don't know why the output is 10, I think the line A a = new B() creates a new instance of class B, I think the result should be 20
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
Why this works like this .. please explain.
First, see Hiding Fields (emphasis added)
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different
In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.
If you expect true overrides, try using methods.
class A {
public int get() {
return 10;
}
}
class B extends A {
#Override
public int get() {
return 20;
}
}
See
A a = new B();
System.out.print(a.get()); // 20
If you really want to see both at once, see this example.
class A {
int i = 10;
}
class B extends A {
int i = 20;
#Override
public String toString() {
return String.format("super: %d; this: %d", super.i, this.i);
}
}
And
A a = new B();
System.out.print(a); // super: 10; this: 20
In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.
If you want 20 as an output you may use getter methods over those instance variables.
class A {
int i = 10;
int getI() {
return i;
}
}
class B extends A {
int i = 20;
int getI() {
return i;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getI());
}
}
Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.
Because you define 2 variables: one in the subclass B, and one with the same name in superclass A.
A a = new B();
a.i; // refers to A.i
If you cast the A to a B, it will access B.i:
System.out.println(((B)a).i);
I think you need to use 1 variable:
class A {
int i;
public A() {
i = 10;
}
}
class B extends A {
public B() {
i = 20;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i); // will print 20
}
Member variable i is already defined in class A.
In order to achieve what you are looking for, change the class B as shown below:
class B extends A {
public B() {
i = 20;
}
}
I have 2 classes that are not the main classes, but I want class B to access the variable from class A. I am not sure how to do it.
public class A (
public int humanCakes;
//This method is called by somewhere, when it is called it adds one
public void humanCakes() {
huamnCakes ++;
}
)
public class B {
public void addUp() {
Cakes = humanCakes + 4;
}
}
Since your variable in class A is public you can do the following
public class B{
int Cakes;
public void addUp(A obj)
{
Cakes = obj.humanCakes + 4;
}
}
Note that you must past the A object into the addUp method in order to get the reference to the humanCakes variable
How does inheritance and polymorphism work with static methods? Could someone explain what the proper output is supposed to be here and how it was derived?
class A { public static int get() { return 17; } }
class B extends A { public static int get() { return 42; } }
Main
A x = new B();
x.get();
The error message,
The static method get() from the type A should be accessed in a static way
I think I know how to access to it in a static way but this is a question from class and its sort of implied that one or the other values would be returned
In our program, we have the class definitions:
class A { public static int get() { return 17; } }
class B extends A { public static int get() { return 42; } }
and somewhere else we declare A x = new B();
What number will the call x.get() return?
The invocation will return the int value 17.
static methods are not inherited.
static methods are bound and invoked based on the type of the expression they are invoked on.
So
x.get();
where x is of type A invokes A's implementation. Note also that static methods don't need an instance to be invoked.
These would work as well.
((A) null).get();
A.get();
...
public static A someMethod() {}
...
someMethod().get();
The message you got is a warning, not an error.
i have a question regarding default constructors in java.
as much as i have read about constructors in java, a default constructor initializes all instance variables to their default values. but what if we define a constructor for a class, then how come variables are initialized to their default values if we want them to ?
suppose i have 2 files
a.java
public class a
{
int x;
public a(int z)
{
if(z > 0)
{
x = z;
}
}
public void get()
{
System.out.println(x);
}
}
and b.java
public class b
{
public static void main(String[] args)
{
a obj = new a(-4);
obj.get();
}
}
now here condition (z>0) fails, so x is initialized to zero. but what exactly does this as their is no default constructor in class a.
Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type.
Source
That means that the compiler will do that for you when you build the program.
In your a class (renamed A below to follow conventions) as you have written it, there is no default constructor. A default constructor for a class is a constructor which is public and has no arguments.
With the code you have written, this will fail:
A a = new A();
As soon as you declare another constructor in a class, there is no default constructor anymore.
As to instance variables, if you do not initialize them explicitly, they are set to default values. That is:
public class A
{
private int x;
public int getX()
{
return x;
}
}
if you do:
final A a = new A();
System.out.println(a.getX());
this will print out 0. The class above is exactly equivalent to:
public class A
{
private int x /* = 0 -- default value for uninitialized int instance variables */;
// redundant
public A()
{
}
public int getX()
{
return x;
}
}
When you declare a variable in java, it's by default initialized as it's default value.
For the primitive types is that 0 (or it's equivalent), for Objects is that null
So in your example has x initialy the value 0 and you never overwrite it.
In java if we dont define any constructor, it takes its self a default constructor which will have default values.while we creating object we intialize values to the constructor.
public class Car{
int numOfWheels;
public Car(int numOfWheels){ //created constructor//
this.numOfWheels=numOfwheels;
}
}
public static void main(string[]args){
Car skoda = new Car(4);
} *//initialized value to the object using constructor in parenthesis//*
public class a
{
int x;
public a(int z)
{
//as we know that every class base class is Object class this constructor first statement is super(); means compiler automatically add this statement that call object class default constructor and initialize default values
if(z > 0)
{
x = z;
}
}
public void get()
{
System.out.println(x);
}
}
public class a
{
int x;
public a(int z)
{
/*As we know that every class base class is Object.....
compiler automatically add super(); that call Object class default constructor
that initialize the value of instance variable */
if(z > 0)
{
x = z;
}
}
public void get()
{
System.out.println(x);
}
}
public class b
{
public static void main(String[] args)
{
a obj = new a(-4);
obj.get();
}
}
//other example is below
/*class A
{
public A()
{
System.out.println("Arjun Singh Rawat and Ashish Chinaliya");
}
}
class B extends A
{
public B()
{
//compiler automatically add super();
}
}
class calling
{
public static void main(String arg[])
{
B bb=new B();
}
}*/
thanks...
public class Demo {
static int a;
Demo(int b )
{
System.out.println(" Constructor");
}
public static int func()
{
System.out.println(a);
return 1;
}
public static void main( String args[])
{
new Demo(func());
}
}
Output
0
Constructor
It's not the default constructor that initializes our fields to their default values ,
In this program, the static field a is being initialized to 0 even though there is no default constructor
added by the compiler. Also it's being initialized to 0 before a constructor being called .
Why does below code prints "1" ?
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class Base {
A getObject() {
System.out.println("Base");
return new B();
}
}
public class CovariantReturn extends Base {
B getObject() {
System.out.println("CovariantReturn");
return new B();
}
/**
* #param args
*/
public static void main(String[] args) {
Base test = new CovariantReturn();
System.out.println(test.getObject() instanceof B);
System.out.println(test.getObject().x);
}
}
Because you are referring to fields, which are not affected by polymorphism. If you instead used getX(), it would've returned 2.
What you are asking is, the value of field x defined in class A (because Base.getObject() returns A). Even though CovariantReturn overrides the method to return B, you are not referring to your object as CovariantReturn.
To expand a bit on how fields are not affected by polymorphism - field access is realized at compile time, so whatever the compiler sees, that's what's accessed. In your case the method defines to return A and so A.x is accessed. On the other hands methods are invoked based on the runtime type. So even if you define to return A but return an instance of B, the method you invoke will be invoked on B.
#kris979 Though you are returning B, i think what makes the difference is that the return type is of A. Hence value of x in A i.e. 1 is printed.
As Bozho pointed out - instance variable are never affected by polymorphism. Let me give you a quick small example.
class Base {
int i = 1;
void method() {
System.out.println("in base");
}
}
class Sub extends Base {
int i = 2;
void method() {
System.out.println("in sub");
}
}
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
obj.method();
System.out.println(obj.i);
}
}
This code will print - in sub and 1