在Java中使用扩展类时的一个小问题

时间:2014-10-22 07:31:58

标签: java polymorphism subclass superclass

编辑:这完全是我的错误,可能是因为凌晨4点匆匆忙忙。代码在技术上是合理的并且工作正常,但是感谢评论我删除了一些冗余以使事情变得更聪明。

我正在开发一个处理Java超级/子类和继承的类项目。虽然90%的代码工作得很好,但是一件小事似乎并不想工作,我有点为什么感到困惑。基本上,我们正在创建一个名为CompactDisc的新类,其中包含产品代码,描述,价格和艺术家等信息。当用户输入适当的代码(sgtp)时,控制台将输出信息。不幸的是,尽管给出了数据,艺术家系列总是空白的。虽然这个项目涉及其他课程,但我只会发布我认为重要的课程。

ProductApp.java:

import java.util.Scanner;

public class ProductApp
{
    public static void main(String args[])
    {
        // display a weclome message
        System.out.println("Welcome to the Product Selector\n");

        // perform 1 or more selections
        Scanner sc = new Scanner(System.in);
        String choice = "y";
        while (choice.equalsIgnoreCase("y"))
        {
            System.out.print("Enter product code: ");
            String productCode = sc.next();  // read the product code
            sc.nextLine();  // discard any other data entered on the line

            // get the Product object
            Product p = ProductDB.getProduct(productCode);

            // display the output
            System.out.println();
            if (p != null)
                System.out.println(p.toString());
            else
                System.out.println("No product matches this product code.\n");

            System.out.println("Product count: " + Product.getCount() + "\n");

            // see if the user wants to continue
            System.out.print("Continue? (y/n): ");
            choice = sc.nextLine();
            System.out.println();
        }
    }
}

Product.java:

import java.text.NumberFormat;

public class Product
{
    private String code;
    private String description;
    private String artist;
    private double price;
    protected static int count = 0;

    public Product()
    {
        code = "";
        description = "";
        price = 0;

    }

    public void setCode(String code)
    {
        this.code = code;
    }

    public String getCode(){
        return code;
    }

    public void setArtist(String artist)
    {
        this.artist = artist;
    }

    public String getArtist(){
        return artist;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public String getDescription()
    {
        return description;
    }

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

    public double getPrice()
    {
        return price;
    }

    public String getFormattedPrice()
    {
        NumberFormat currency = NumberFormat.getCurrencyInstance();
        return currency.format(price);
    }

    @Override
    public String toString()
    {
        return "Code:        " + code + "\n" +
               "Description: " + description + "\n" +
               "Price:       " + this.getFormattedPrice() + "\n";
    }

    public static int getCount()
    {
        return count;
    }
}

CompactDisc.java:

public class CompactDisc extends Product
{
    private String artist;

    public CompactDisc()
    {
        super();
        artist = "";
        count++;
    }

        @Override
    public void setArtist(String artist)
    {
        this.artist = artist;
    }

    @Override
        public String getArtist(){
        return artist;
    }

        @Override
    public String toString()
    {
        return super.toString() +
            "Artist:      " + artist + "\n";
    }
}

ProductDB.java:

public class ProductDB
{
    public static Product getProduct(String productCode)
    {
        // In a more realistic application, this code would
        // get the data for the product from a file or database
        // For now, this code just uses if/else statements
        // to return the correct product data

        Product p = null;

        if (productCode.equalsIgnoreCase("java") ||
           productCode.equalsIgnoreCase("jsps") ||
           productCode.equalsIgnoreCase("mcb2"))
        {
            Book b = new Book();
            if (productCode.equalsIgnoreCase("java"))
            {
                b.setCode(productCode);
                b.setDescription("Murach's Beginning Java");
                b.setPrice(49.50);
                b.setAuthor("Andrea Steelman");
            }
            else if (productCode.equalsIgnoreCase("jsps"))
            {
                b.setCode(productCode);
                b.setDescription("Murach's Java Servlets and JSP");
                b.setPrice(49.50);
                b.setAuthor("Andrea Steelman");
            }
            else if (productCode.equalsIgnoreCase("mcb2"))
            {
                b.setCode(productCode);
                b.setDescription("Murach's Mainframe COBOL");
                b.setPrice(59.50);
                b.setAuthor("Mike Murach");
            }
            p = b; // set Product object equal to the Book object
        }
        else if (productCode.equalsIgnoreCase("txtp"))
        {
            Software s = new Software();
            s.setCode("txtp");
            s.setDescription("TextPad");
            s.setPrice(27.00);
            s.setVersion("4.7.3");
            p = s; // set Product object equal to the Software object
        }
 else if (productCode.equalsIgnoreCase("sgtp"))
        {
            CompactDisc c = new CompactDisc();
            c.setCode("sgtp");
            c.setDescription("Sgt. Pepper's Lonely Hearts Club Band");
            c.setPrice(15.00);
            c.setArtist("The Beatles");
            p = c; // set Product object equal to the CompactDisc object
        }
        return p;
        }

输出。如你所见,艺术家是空的:

Welcome to the Product Selector

Enter product code: sgtp

Code:        sgtp
Description: Sgt. Pepper's Lonely Hearts Club Band
Price:       $15.00
Artist:      

Product count: 1

Continue? (y/n): 

我有预感我在ProductDB.java中做错了什么,但我可能错了。提前谢谢。

4 个答案:

答案 0 :(得分:1)

我无法重现您的错误。我得到了结果:

Welcome to the Product Selector

Enter product code: sgtp

Code:        sgtp
Description: Sgt. Pepper's Lonely Hearts Club Band
Price:       15,00 €
Artist:      The Beatles

Product count: 1

Continue? (y/n):

Product的艺术家字段被CompactDisk隐藏。你应该真的改变它以拥有合理的设计。但我不明白为什么这不起作用。

答案 1 :(得分:0)

产品确实不应该是artist字段,也不应该是setArtist()

这里发生的是你可以覆盖一个方法,但你不能覆盖一个字段,只需隐藏它。当您访问字段时,它取决于引用的类型,而不是对象的实际类。由于artist字段中没有任何内容在构建它时被CompactDisk隐藏,因此您将获得一个空字段。

答案 2 :(得分:0)

由于声明

,您的问题仍然存在
 Product p

后来成了

 Product p = new CompactDisc();

该行表示,您的变量仍然引用类型ProductCompactDisc

中的方法

更改

  @Override
public String toString()
{
    return super.toString() +
        "Artist:      " + artist + "\n";
}

  @Override
public String toString()
{
    return super.toString() +
        "Artist:      " + this.getArtist() + "\n";
}

当您打印变量时,它仍指向声明的LHS,当您访问方法时,它属于RHS。

作为旁注,你有一个设计问题(评论相同的早期)以及在父母和孩子中有多个艺术家变量。在一个级别删除它,使您的程序更清晰。

答案 3 :(得分:0)

由于p是具有Product字段的artist,因此当您调用toString方法时,您将获得其artist中包含的值} field,这是空字符串。

这主要是因为您无法覆盖字段。你是hiding the child field with the parent field

在子类中,超类中的字段不能通过其简单名称引用,父类也是如此。

由于您没有以奇怪的方式在artist中使用Product,我建议您在Product类中删除它并使用CompactDisk