Accessing variable from other class - java

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

Related

Cannot get value of property from extending class

I have two Java classes, one of which inherits from other. They are somewhat like the following:
A.java:
public class A {
public String invocations[] = {"foo"};
public A() {
// do stuff
}
}
B.java:
public class B extends A {
public String invocations = {"bar", "baz"};
public B() {
super();
}
}
In this example, assuming I create an instance of B and get its invocations property, it returns {"foo"} instead of the expected {"bar", "baz"}. Why is this, and how can I get the {"bar", "baz"}?
You have one variable hiding another one. You can refer to a variable in a super class by using a cast to the type explicitly. (I am assuming you fix the syntax errors)
public class Main {
static class A {
public String[] invocations = {"foo"};
}
static class B extends A {
public String[] invocations = {"bar", "baz"};
}
public static void main(String... args) {
B b = new B();
System.out.println("((A)b).invocations=" + Arrays.toString(((A) b).invocations));
System.out.println("b.invocations=" + Arrays.toString(b.invocations));
}
}
prints
((A)b).invocations=[foo]
b.invocations=[bar, baz]

Accessibility between objects (instances) of the same class

When one object of a class has a reference to another object of
the same class, the first object can access all the second object’s
data and methods (including those that are private).
I took this sentence from a book. But I couldn't figure out actually what it means.
It means that private members are visible to other instances of the same class. For example:
class A {
private int v;
public boolean isSameV(A other) {
return this.v == other.v; // can acccess other.v
}
}
It means that if you have a class that looks like this
public class A {
private int number;
private A otherInstance;
public int number2;
public void DoStuff() {
...
}
}
you can access A.number in the DoStuff method (or any other class method) even although number is actually private.
e.g.
public class A {
...
public void DoStuff() {
this.otherInstance.number = 42;
^^^^^^^
cannot access private members here
}
}
is perfectly fine, while
public class B {
private A aInstance;
public void DoStuffToo() {
this.aInstance.number = 42;
}
}
would not compile, because B cannot access A's private members.
Good question actually, I faced similar problem when I started learning Java, here is how it looks in practice:
public class A {
private String example;
protected int anotherOne;
public A(){
}
public A(A a){
this.example = a.example; // here we get access to private member of another object of same class
this.anotherOne = a.anotherOne; // it works for protected as well
}
// This works for methods not just constructor, lets consider we want to swap value of example:
public void swapExample(A a){
String temp = a.example;
a.example = this.example;
this.example = temp;
}
}
Private fields can be accessed from inside of the class, by this construction you can access all the field of an instance of Foo without getters and setters when you are in class Foo :
public class Foo {
private String name;
public int sumLetter(Foo b) {
return this.name.length() + b.name.length();
}
}
The doc : Declaring Member Variables :
private modifier — the field is accessible only within its own class.

Abstract Class and toString() method

I am a little confused on how to set up the TestHomework method so that it prints properly when using the toString() method. Right now when I run the main method it prints "null - 0" but what I would like it to say is "Math - 6". This program is supposed to extend an abstract class. It is supposed to say how many pages there are for homework and for what subject.
public abstract class Homework {
private int pagesToRead;
private String typeHomework;
{
// initialise instance variables
pagesToRead = 0;
typeHomework = "none";
}
public Homework(int pages, String hw) {
this.pagesToRead = pages;
this.typeHomework = hw;
}
public abstract void createAssignment(int p);
public int getPages() {
return pagesToRead;
}
public void setPagesToRead(int p) {
pagesToRead = p;
}
public String getTypeHomework() {
return typeHomework;
}
public void setTypeHomework(String hw) {
typeHomework = hw;
}
}
public class MyMath extends Homework {
private int pagesRead;
private String typeHomework;
public MyMath(int pages, String hw) {
super(pages,hw);
}
public void createAssignment(int p) {
setTypeHomework("Math");
setPagesToRead(p);
}
public String toString() {
return typeHomework + " - " + pagesRead;
}
}
public class TestHomework {
public static void main(String[] args) {
MyMath one = new MyMath(6, "Math");
one.createAssignment(6);
System.out.println(one);
}
}
That's because you are defining the 2 properties (that one of them happen to have the same name as one of the abstract class's) but you are not initializing them, you are initializing those of the abstract class. (So their values is always set to their type's default)
You need to drop those from the MyMath class, & define the toString method in your abstract class: it's the one to be used by default by its inheriting classes.
public abstract class Homework {
private int pagesToRead;
private String typeHomework;
// Same code
// Define the toString here
#Override
public String toString() {
return typeHomework + " - " + pagesToRead;
}
}
public class MyMath extends Homework {
// You don't need to define any extra attributes
public MyMath(int pages, String hw) {
super(pages,hw);
}
public void createAssignment(int p) {
setTypeHomework("Math");
setPagesToRead(p);
}
}
public static void main(String[] args) {
// Calls the constructor of the MyMath class, which in turn
// invokes the constructor of its superclass, the 'Homework' class
MyMath one = new MyMath(6, "Math");
one.createAssignment(6);
// Invokes the toString of the MyMath class. Since it does not have one,
// The toString method of its superclass (Homework) is called.
System.out.println(one);
}
Your derived class has its own typeHomework and pagesRead fields, which are never set (even though the base class happens to have fields with the same names). Therefore, they stay null and 0.
You should delete those fields and use the data from the base class, via the public getter methods.
Why it doesn't work:
Be careful you redeclared the attribute typeHomework of you parent class. Attributes are automatically added to your extending class so you don't have to write them again.
By redeclaring it you confused the compiler, viewing your code in debug shows, that your one object contains your typeHomework twice:
typeHomework = null // The one from the super class
typeHomework = "Math" // The one from your child class
Your method now uses the typeHomework from your super-class therefor the output is null!
pagesRead is 0 because you are setting the pagesToRead of your super-class to 6(not pagesRead!) when calling setPagesToRead(p);.
Some style tips
Use the #Override annotation when overriding methods like this:
#Override
public void createAssignment(int p) {
setTypeHomework("Math");
setPagesToRead(p);
}
It's not really needed but it's good practice (readers of your code know that it overrides something).
When referring to attributes of your class it's also good practice to use the this statement so it's clear, that you're referring to an attribute and not a local variable:
#Override
public String toString() {
return this.typeHomework + " - " + this.pagesRead;
}

private member accessible via public method

The private modifier specifies that the member can only be accessed in its own class. But am I able to access it using a public method that get inherited from base class. Can someone explain me why? Does this mean object of Child class contain a member called b?
Here's the code:
package a;
public class Base {
private int b;
public int getB() {
return b;
}
public void exposeB() {
System.out.println(getB());
}
public Base(int b) {
this.b = b;
}
}
package b;
public class Child extends Base {
Child(int b) {
super(b);
}
public static void main(String args[]) {
Child b = new Child(2);
// Prints 2
System.out.println("Accessing private base variable" + b.getB());
}
}
you are not accessing the private variable in your super class directly. you are implementing the concept of Encapsulation. you are using the public getter method(in this case getB()) to make your private data accesed by other classes. thus, you can access private variable b through public getter but you never cant access b directly on its instace from another/subclass
In class Base, the field b is private but getB() is public so anybody can call that method.
What you can expect to fail compilation is something like:
System.out.println( "Accessing private base variable" + b.b );
(unless that line is called from within a method of Base itself).
You will not be able to access b directly in Child because it is private. You can, however, use the base-class's getB method which is public (and hence can be called anywhere).
To allow only extending classes and other classes in your package to access the field, you can declare it as protected.
class A {
private int n;
public A(int n) { this.n = n; }
public int n() { return n; }
}
class B extends A {
public B(int n) { super(n); }
public void print() { System.out.println(n); } // oops! n is private
}
class A {
protected int n;
public A(int n) { this.n = n; }
public int n() { return n; }
}
class B extends A {
public B(int n) { super(n); }
public void print() { System.out.println(n); } // ok
}
The private modifier means that you can't reference that field outside the class. Because getB() is public, however, you can reference that method. The getB() method can reference the private b field, because it's inside the class, and therefore can access it.
Private variable means that you can't access directly the variable from its class.... Declaring that variable private means that you can't do this
Myclass.myprivatevariable = 3
This will throw a compile error complaining that myprivatevariable is not visible fro the outside
But, as you did.... Declaring an internal method as getter or setter, public, you are allowing the user, only just through that method, to access indirectly that variable... That is always the preferred way to do.

Object Oriented Class Communication

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();
}
}

Categories