【问题标题】:Creating Java Classes创建 Java 类
【发布时间】:2014-07-23 06:29:36
【问题描述】:

我目前正在开发一个库存程序,该程序涉及一个一维数组、2 个类(Store 和 Book)以及其他一些东西,例如方法和构造函数。

我猜你可以说的主类 Store 类应该包含 main() 方法,并且应该从文件中读取购买列表,使用适当的消息(ISBN 编号,数量、价格或问题(例如缺货或没有)),存储最多 15 本书类型书籍的数组,在库存文件中读取的方法,处理购买的方法,打印的方法结账时的库存以及售出的书籍数量和结账时的金额。

Book 类包括 book 对象(每个 book 对象都包含 ISBN String、price double 和副本 int)、构造函数、getter 和 setter 以及打印信息的方法。

由于该数组应该在 Store 类中创建,但它的类型是 Book 并且由 book 对象组成(我假设?),我无法弄清楚如何正确执行此操作(分配isbn 的值、价格、复制变量、正确设置构造函数等)。

更新 我现在遇到的主要问题是能够从我的 printInfo 方法打印图书对象。我在该方法的打印语句中收到一条错误消息,指出“找不到符号。符号:书”。我还不能真正看到程序是否真的在工作,因为这是我现在需要看到的(打印出来的书对象),然后我开始添加更多方法来做其他依赖于本书的事情对象是正确的。

这是我目前想出的代码:

Store 类:

import java.util.Scanner;
import java.io.*;

public class Store {
    public static void main(String[] args) throws Exception {
        Book[] books = readInventory();

        for (Book : books) {
            System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
            book.getISBN(), book.getPrice(), book.getCopies()); 
        }
    }

    public static Book[] readInventory() throws Exception {
        Book[] books = new Book[15];
        java.io.File file = new java.io.File("../instr/prog4.dat");
        Scanner fin = new Scanner(file);
        String isbn;
        double price;
        int copies;

            while (fin.hasNext()) {
                for(int i = 0; i < books.length; i++) {
                isbn = fin.next();
                price = fin.nextDouble();
                 copies = fin.nextInt();

                 Book book = new Book(isbn, price, copies);
                 books[i] = book;
                }
            }
            fin.close();
            return books;
    }

    public static void printInfo(Book[] books) {
        System.out.println(book);
    }
}

这是我的图书课:

public class Book {
    private String isbn;
    private double price;
    private int copies;

    public Book(String isbnNum, double priceOfBook, int copiesInStock) {
        isbn = isbnNum;
        price = priceOfBook;    
        copies = copiesInStock;
    }

    public String getISBN() {
        return isbn;
    }

    public double getPrice() {
        return price;
    }

    public int getCopies() {
        return copies;
    }

    public void setISBN(String isbn) {
        this.isbn = isbn;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public void setCopies(int copies) {
        this.copies = copies;
    }

    @Override
    public String toString() {
        return String.format("ISBN: %s, Price: %f, Copies: %d%n",
                this.getISBN(), this.getPrice(), this.getCopies());
    }
}

这是我第一次使用类,或者至少在同一个程序中创建多个类,所以我仍在试图弄清楚它是如何工作的。我一直在阅读我在网上找到的教程,该教程有些帮助,但我无法将其应用于这种特定类型的程序。

任何建议将不胜感激。

【问题讨论】:

  • String[] books = new String[15]; 应该是Book[] books = new Book[15];,然后当您加载文件时,您只需将每本书的一个新实例分配给数组books[i] = new Book(isbn, price, copies);的一个元素

标签: java arrays class


【解决方案1】:

您好,很高兴看到您在进入这里之前已经努力实际尝试了一些东西。到目前为止,您所做的一切都很好。但是您现在真正需要的是class Book 中的getter 和setter 方法。这些将允许您返回或设置对象的变量值。

public class Book {
    private String isbn;
    private double price;
    private int copies;

    public Book(String isbnNum, double priceOfBook, int copiesInStock) { // Constructor?
        isbn = isbnNum;
        price = priceOfBook;
        copies = copiesInStock;
    }

    public String getISBN() {
        return this.isbn;
    }

    public double getPrice() {
        return this.price;
    }

    public int getCopies() {
        return this.copies;
    }

    public void setISBN(String value) {
        this.isbn = value;
    }

    public void setPrice(double value) {
        this.price = value;
    }

    public void setCopies(int value) {
        this.copies = value;
    }
}

这应该可以帮助您走上正轨。取决于您希望信息如何出现,取决于您是否在每个 get 函数中添加 System.out.println("ISBN: " + this.isbn); 等等,或者您可以声明一个单独的函数 getInfo,它只打印每个函数。或者,如果您将其退回商店,您可以随时以这种方式打印它。还有一点需要注意的是,当您创建Book 对象数组而不是字符串时,您一直将books 声明为Book[] books = new Book[15]。如果您需要更多帮助,请告诉我。

【讨论】:

  • 太棒了,这真的很有帮助。在 setter 方法上,我从文件中获取的 String 值、double 值和 int 值是实际值,还是只是名为 value 的变量?对不起,我敢肯定,愚蠢的问题,但就像我说的,我还在学习。如果它们是实际值,我很难弄清楚如何设置这些值?
  • 听到我至少在正确的轨道上感到非常欣慰我担心这会变得如此错误我会在这个网站上被嘲笑哈。
  • 另外,由于数组的索引从 0 开始,数组的声明不是 Book[] books = new Book[14] 吗?
  • @BethTanner,不,当我们这样创建数组时,里面的数字是数组中元素的数量,即 15。然而,第 15 个元素在索引 14 处。
  • value 只是一个变量。例如,如果您创建了一个名为genericBookBook 对象并执行了genericBook.setPrice(5),它将使用该值5 来设置该对象。只要函数将对象变量设置为该值,您就可以简单地调用value。例如:setVariable(string meow),然后是this.variable = meow
【解决方案2】:

1.你不应该使用 String Array。你应该声明 Book Array。那么分配您的 Book 对象会更容易。

例如 书[]书=新书[15]; books[i] = new Book(isbnNum,priceOfBook,copiesInStock);

2.因为 Book 类中的变量是用私有类型声明的。您应该在 Book 类中创建 get 方法来获取任何对象中的变量。

例如

public String getbnNum()
{
return isbn;
}

public double getprice(){
return price;
}

public int getcopies(){
return copies;
}

【讨论】:

  • 您的示例中缺少Book(新书(isbn...))
【解决方案3】:

我在代码中为你写了 cmets。我必须假设您的文件读取代码是正确的,因为我没有该文件。

import java.util.Scanner;

public class Store {

    /* 
     * This is the main method. It is where the code that starts off the
     * application should go.
     */
    public static void main(String[] args) throws Exception {
        // Here, we take the array returned by the method and set it to a local variable.
        Book[] books = readInventory();

        // This is an alternative notation than a normal for-loop.
        for (Book book : books) {
            System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
                    book.getISBN(), book.getPrice(), book.getCopies());
        }

    /* Alternative to above.
        for (int i = 0; i < books.length; i++) {
            Book book = books[i];
            System.out.printf("ISBN: %s, Price: %f, Copies: %d%n",
                    book.getISBN(), book.getPrice(), book.getCopies());
        }
    */
    }

    // We add the return type of Book[] so we can get a reference to our array.
    public static Book[] readInventory() throws Exception {
        Book[] books = new Book[15];
        java.io.File file = new java.io.File("../instr/prog4.dat");
        Scanner fin = new Scanner(file);

        // These variables don't need to be initialized yet.
        String isbn;
        double price;
        int copies;

        while (fin.hasNext()) {

            // Fill the books array with Book objects it creates from the file.
            for (int i = 0; i < books.length; i++) {
                isbn = fin.next();
                price = fin.nextDouble();
                copies = fin.nextInt();

                Book book = new Book(isbn, price, copies);
                books[i] = book;
            }
        }
        fin.close();
        return books;
    }
}

书籍类:

public class Book {
    private String isbn;

    /*
     * Careful using double as your type for variables that hold money values.
     * If you do any division, you can end up getting answers different than
     * what you might expect due to the way Java handles remainders. For that,
     * make price a Currency type, which you can import from Java.util
     */
    private double price;

    private int copies;

    public Book(String isbnNum, double priceOfBook, int copiesInStock) {
        isbn = isbnNum;
        price = priceOfBook;
        copies = copiesInStock;
    }

    // This is an example of a getter method, which we need since our isbn is
    // declared as private. Now, other methods can still read what isbn is.
    public String getISBN() {
        return isbn;
    }

    public double getPrice() {
        return price;
    }

    public int getCopies() {
        return copies;
    }

    /*
     * We can use the "this" keyword to refer to this instance's isbn variable,
     * instead of the local variable isbn that was passed to the method.
     * Therefore, in this tricky notation we are setting the object's isbn
     * variable to the isbn variable passed to the method.
     */
    public void setISBN(String isbn) {
        this.isbn = isbn;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public void setCopies(int copies) {
        this.copies = copies;
    }
}

另请注意,打印每本书信息的更高级方法是在Book 类中创建一个toString() 方法,该方法覆盖它从通用Object 类继承的默认toString 方法。您应该使用称为覆盖注释的特殊约定来执行此操作,因为当我们从超类(Object 是所有对象的超类,包括 Book)重新定义方法时,这被认为是一种很好的做法。

@Override
public String toString() {
    return String.format("ISBN: %s, Price: %f, Copies: %d%n",
            this.getISBN(), this.getPrice(), this.getCopies());
}

例如,这将允许我们简单地调用System.out.println(book);,并且还意味着我们不必在我们想要打印一本书的每个地方都重写所有这些代码。这是对象的一个​​重要原则——它们通常应该照顾好自己。

【讨论】:

  • 非常感谢!不过,我遇到了一些编译器错误。在: for (Book : books) { line I'm getting 4 errors, (not a statement for (Book : books) { 有一个 ^ 指向 Book,另一个不是语句错误,箭头指向 :,还有两个';' 预期错误,一个带有 ^ 就在 Book 之后,另一个带有它指向 Books 之前)。
  • 在代码的 Override 部分的末尾我有两个错误(它们都是类、接口或枚举预期错误,一个箭头指向 String toString() 上的 S { 和 @Override 段的右括号中的另一个)。任何想法我做错了什么,我也会在原始问题中更新我的代码,以便您查看。
  • 别在意第二条评论,我在@Override 部分之前不小心关闭了课程,现在没有收到这两个错误。
  • 那行应该是for (Book book : books) {,第一个单词Book是大写的,告诉Java我们想要什么类类型,第二个单词book,你缺少的那个,是我们的名字给局部变量,但它可以是我们想要的任何东西,最后一个词books 是数组。如果这仍然不起作用,您始终可以使用正常表示法。我将对其进行编辑以将其放在原件旁边的评论块中。
  • 哦,好吧,我想我一定是太快跳过那条线了,谢谢你清理它。
猜你喜欢
  • 2012-04-30
  • 2011-04-05
  • 2016-10-24
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
相关资源
最近更新 更多