Java не распознает поле из другого класса

Итак, мой код Java включает определение класса конструктора объекта:

public static class bookID{
    bookID(String startAuthor, String startGenre, int startNumID){
        String author = startAuthor;
        String genre = startGenre;
        int numID = startNumID;
        String finalID = author + genre + Integer.toString(numID);
    }
}

И затем создание экземпляра класса после обработки ввода пользователя (в основном методе программы).

bookID newID = new bookID(authFinal, genre, numID); 
books.add(newID);
System.out.println(newID.finalID);

Однако последняя строка выдает ошибку, говоря, что она "не может найти символ" переменной finalID, несмотря на то, что newID уже вызывается, и она должна иметь экземпляр finalID в качестве поля. Кто-нибудь может указать, что я здесь делаю не так?

Вот ошибка:

Bookstore.java:100 ошибка: не удается найти символ

System.out.println(newID.finalID);

символ: переменная finalID

location: переменная newID типа bookID

4 ответа

В объектно-ориентированном программировании переменные-члены ("поля" в java), как правило, не доступны вне области видимости класса (в некоторых языках они по умолчанию, но в java они не доступны, если не объявлены как public, что обычно не рекомендуется).

Если вы хотите иметь доступ к этим вещам, вам нужно сделать открытые функции-члены "getter" или "setter" в вашей реализации класса для этого. Например, определяя

public String getFinalID() {
    return finalID;
}

в вашем классе bookID (также, пожалуйста, следуйте соглашениям об именах для Java, если вы не получили указаний об этом - это должно быть написано с большой буквы как BookID, поскольку это класс) позволит вам прочитать значение finalID в любом экземпляре класса bookID. Ваш код после обработки пользовательского ввода изменится на

bookID newID = new bookID(authFinal, genre, numID); 
books.add(newID);
System.out.println(newID.getFinalID());  //<-- notice the change here

Это сделано для того, чтобы ваши публичные пользователи не имели прямого доступа к внутренним компонентам ваших классов, если вы специально не разрешите это. В этом случае, используя геттер, вы не позволяете пользователю перезаписывать то, что хранится в finalID, как они могли бы, если бы у них был прямой доступ, выполняя что-то, как показано ниже:

bookID newID = new bookID(authFinal, genre, numID); 
books.add(newID);
newID.finalID = "something else";

Но, конечно, вы все еще можете сделать это, если действительно хотите реализовать метод установки:

public void setFinalID(newFinalID) {
    finalID = newFinalID;
}

В вашем коде много проблем.

класс не может быть статичным

Во-вторых, название вашего объекта не представляет его хорошо. Хорошее начало может быть:

public class Book {}

Вы хотите сказать, что ваша книга может быть определена startAuthor, String startGenre, int startNumID. Для меня начало не имеет никакой смысловой ценности, возможно, есть для вашей необходимости. Но я бы сказал:

public class Book {
     private String author;
     private String genre;
     private String id;

     public Book(String author, String genre, String id) {
            this.author=author;
            this.genre=genre;
            this.id=id;
     }

     public String getId(){ 
          return this.id; 
     }
     public String getAuthor(){ 
          return this.author; 
     }
     public String getGenre(){ 
          return this.genre; 
     }
}

Использование геттеров и сеттеров является соглашением в Java. Это инкапсуляция, имейте это в виду, она всегда одинакова, когда вы понимаете логику.

Теперь вы можете использовать это doint

Book book = new Book();
book.getId();

Тем не менее, это строки, которые вы написали:

String author = startAuthor;

полностью отличается от

this.author=author;

В вашем случае автор будет свободен в конце инструкции блока. Я думаю, что вы хотите дать это атрибуту книги. это представляет экземпляр книги, поэтому this.author ссылается на атрибут Book, а автор без this представляет ближайший определенный атрибут, который является параметром конструктора.

Наконец, если ваш finalID является комбинацией ваших переменных. Я не понимаю, почему вы должны сохранить это. это зависит от того, что вам нужно и как вам это нужно, но если вы хотите просто описать свой объект, этого достаточно.

@Override 
public String toString() {
    return author+genre+id;
} 

Во-первых, ваши поля должны быть глобальными для класса и предпочтительно объявлены как закрытые.

public class bookID{

    private String author;
    private String genre;
    private int numID;
    private String finalID;

Затем капитальный ремонт конструктора, чтобы выглядеть так

bookID(String startAuthor, String startGenre, int startNumID){
    this.author = startAuthor;
    this.genre = startGenre;
    this.numID = startNumID;
    this.finalID = author + genre + Integer.toString(numID);
}

наконец, создайте геттеры для полей в соответствии с соглашением:

public String getAuthor(){
    return this.author;
}

также вы можете использовать оболочку, чтобы избежать использования Integer.toString() и просто создать поле типа Integer, а затем вызвать метод toString () для него

finalID должен быть глобальной публичной переменной, чтобы сделать это. Или частным методом get.

Если вы сделаете первое, вы можете позвонить newID.finalID. С помощью getter вы можете вызвать newID.getFinalID();

Способ 1:

public static class bookID{
    public String finalID;
    bookID(String startAuthor, String startGenre, int startNumID){
        String author = startAuthor;
        String genre = startGenre;
        int numID = startNumID;
        finalID = author + genre + Integer.toString(numID);
    }
}

Способ 2:

 public static class bookID{
        private String finalID;
        bookID(String startAuthor, String startGenre, int startNumID){
            String author = startAuthor;
            String genre = startGenre;
            int numID = startNumID;
            finalID = author + genre + Integer.toString(numID);
        }

        getFinalID(){
            return finalID;
        }
    }
Другие вопросы по тегам