在Java中使用扩展类时出现的小问题

在Java中使用扩展类时出现的小问题,java,polymorphism,subclass,superclass,Java,Polymorphism,Subclass,Superclass,编辑:这完全是我的错误,可能是因为凌晨4点赶时间。代码在技术上是合理的,运行良好,不过感谢评论,我删除了一些冗余,使事情变得更加智能 我正在从事一个类项目,该项目处理Java超/子类和继承。虽然90%的代码都能正常工作,但有一件小事似乎不想工作,我有点困惑为什么。基本上,我们正在创建一个名为CompactDisc的新类,该类包含产品代码、描述、价格和艺术家等信息。当用户输入适当的代码(sgtp)时,控制台将输出信息。不幸的是,艺术家行始终是空白的,尽管提供了数据。虽然这个项目还涉及其他课程,但我

编辑:这完全是我的错误,可能是因为凌晨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中做错了什么,但我可能错了。提前谢谢。

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

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
one隐藏。你真的应该改变它,让它有一个合理的设计。但我不明白为什么这不起作用。

产品中确实不应该有
artist
字段或
setArtist()


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

您的问题是由于声明而存在的

 Product p
后来成了

 Product p = new CompactDisc();
这一行意味着,您的变量仍然引用类型
Product
CompactDisc

改变

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

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


作为旁注,在父级和子级中都有多个艺术家变量,因此您也有一个设计问题(前面的注释相同)。从一个层次上删除它,让你的程序更清晰。

因为
p
是一个
产品
,它有一个
艺术家
字段,当你调用
toString
方法时,你会得到他
艺术家
字段中包含的值,这是一个空字符串

这主要是因为您无法覆盖字段。你是

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


既然您在
产品中没有以奇怪的方式使用
艺术家
,我建议在
产品
类中去掉它,并使用
压缩磁盘
一个。

为什么
压缩磁盘
设置艺术家
上有一个
覆盖
符号?
Product
@Narmer中没有
setArtist
方法
Prodcut
中有
setArtist
方法。就在上面
getArtist
。哦!我的错!滚动太多,对不起!编辑:汤姆的忍者。不,他们很好。是我,我和鼠标卷轴打了一架:D将给我一个空白的艺术家领域@ev88从图像中我可以看到getArtist()方法,ethod仍然没有使用。你能写下这个.getArtist()
吗?对不起,快凌晨4点了,我一定没看到。遗憾的是,它仍然是空白的。你能在调用setArtist和getArtist方法时设置一个断点并让我知道它们在调用哪些类吗?我很肯定这一点。getArtist()做到了,因为它在完成主项目的完整运行后现在可以工作了。我不知道为什么在做了你的建议之后没有马上。所以,谢谢!
  @Override
public String toString()
{
    return super.toString() +
        "Artist:      " + this.getArtist() + "\n";
}