1

I am completely new to Java.

I was practicing a code about a person eating some fruit. I have 3 classes

Fruit Class:

public class Fruit {
    String fruitname = "grapes";
}

Person Class:

public class Person {
    void eat(Fruit f) {
        System.out.println("person is eating " + f.fruitname); // how can I do f.fruitname
    }
}

Test Class:

public class TestFruit {
    public static void main(String[] args) {
        Person p = new Person(); // person object
        Fruit f = new Fruit(); // fruit object
        p.eat(f);
    } // eat method of person class
}

output:

person is eating grapes

For accessing fields of a class, Object of that class is created.

My question is:

In Person class, how can I access fruitname field of Fruit class (i.e., writing f.fruitname) without instantiating Fruit class in Person class?

fruitname is a data member of Fruit class and instance member don't exist until object is created.

I have just started learning Java, and I am stuck here. Please help me to understand.

Victor M Perez
  • 2,185
  • 3
  • 19
  • 22
  • You can declare class as static like :- static class Fruit { String fruitname = "grapes"; } – Xay Mar 25 '18 at 18:00
  • I am still away from 'static' concept in Java. Practicing with creating simple objects only now. –  Mar 25 '18 at 18:02
  • try giving Fruit an accessor (getter) method, to return the name. this is standard Java stuff. – Patrick Parker Mar 25 '18 at 18:03
  • 1
    I don' understand your question. Your code already does what you want: the fuitname of the Fruit is accessed from the Person.eat() method, and the Person class does not instantiate any Fruit. it receives it as argument from the TestFruit main method. – JB Nizet Mar 25 '18 at 18:03
  • Kindly go through this link it will help you to learn java https://www.javatpoint.com/static-keyword-in-java – Xay Mar 25 '18 at 18:04
  • @JBNizet yeah code is fine. I got confused on writing f.fruitname in print statement. Up till now, I learned that only after creating Fruit object, I can access f.fruitname. Here I haven't instantiate Fruit class. –  Mar 25 '18 at 18:10
  • 1
    Well, first off you are not instantiating `Fruit` in `Person` - you do that outside in your main-method. What you do is pass the `Fruit` instance `f` to the `eat()` function of `Person` which requires such an instance. Insice `eat()` you want to access the `fruitname` of the `Fruit`. You can do that by accessing a public member, or access it via getter method. – Stefan Falk Mar 25 '18 at 18:14

4 Answers4

3

What you're doing does not work because you're not declaring the member field as public:

public String fruitname = "grapes";

Only then you can even compile this:

System.out.println("person is eating " + f.fruitname);

Note that in Java fields are package private per default (see also). This means that the field can be private but in this case you can only access this field in classes which reside in the same package.


However, in general one creates getter and setter methods like this:

public class Fruit {

    private String fruitname = "grapes";

    public String getFruitname() {
        return fruitname;
    }

    public void setFruitname(String fruitname) {
        this.fruitname = fruitname;
    }
}

which will allow you to access the class member fruitname like this:

public class Person {
    public void eat(Fruit f) {
        System.out.println("person is eating " + f.getFruitname());
    }
}

Depending on your IDE you might be able to right click the field (or somewhere in the class) and find something like Generate.. > Getters & Setters which makes the whole act less annoying.

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378
1

Your problem is, that you dont encapsulate the Fruit class correctly.

The current field is package-private so only the class itself and other classes from the same package can access the field. When starting to use concurrency you really need to encapsulate your fields right in order to guard them aswell.

I suggest looking into the Annotation-Preprocessor Lombok since it will help you a lot by generating methods later on. You would just need to add two annotations above your class or the fields in it that should be encapsulated.

An encapsulated and documented version of your Fruit class would look like this:

package me.yourname.yourproject;

import javax.annotation.Nullable;

public class Fruit {

  @Nullable
  private String name;

  /**
   * Constructs a fruit without a name.
   */
  public Fruit(){
  }

  /**
   * Constructs a fruit with an initial name.
   *
   * @param name The fruits initial name.
   */
  public Fruit(String name){
    this.name = name;
  }

  /**
   * Sets the name of the fruit.
   *
   * @param name The fruits new name.
   */
  public void setName(@Nullable String name){
    this.name = name;
  }

  /**
   * Gets the fruits current name.
   */
  @Nullable
  public String getName(){
    return this.name;
  }

}
Ehenoma
  • 13
  • 5
  • I think your answer is overkill considering @deer is a newbie. @deer only needed to know how to access the property in class fruit. I propose a simple answer such as making the field name `fruitname` a public static variable, then advise on how to make the approach more OOP-like – mugume david Mar 25 '18 at 18:47
0

So it looks like you need to read up on Creating an object in Java. That's not a bad thing! OO design is hard when you're a beginner.

To answer you're question, you have to instantiate the fruitname object, and then mark it public (or preferably write a getter/setter)

public class Fruit {
    private string name;
    public Fruit(String name) {
        this.name=name;
    }
    public String getName() {
        return this.name;
    }
}

Create this object with something like:

Fruit f=new Fruit("peach");
System.out.println(f.getName());
Michael S
  • 166
  • 2
  • 7
0

If what you want is to access it in Person without having an instance of Fruit:
Your fruitname is an instance variable. By declaring it 'static' you make it a class member and then you can access it using Fruit.fruitname
You can make it 'public' to allow access from anywhere. As in

public static string fruitname = "grapes"; 

Now you don't need an instance of Fruit to access fruitname.
Your Person call can look as follows:

public class Person {
    void eat() {
        System.out.println("person is eating " + Fruit.fruitname); 
    }
}
inor
  • 2,781
  • 2
  • 32
  • 42