当前位置: 首页 > 知识库问答 >
问题:

使用两个不同的构造函数创建单个对象[duplicate]

彭海阳
2023-03-14

我有一个Card类,它包含两个构造函数,你可以在下面的代码中看到。问题是,每个卡片对象包含2个字符串和2个图像,因为我想保存这些对象,所以我必须将图像的路径保存为字符串,然后检索它们,因此需要2个构造函数。然而,使用一些打印语句,我发现每当检索到一张卡片时,就会创建两个独立的对象:一个正常的对象和另一个空的对象。我知道这是因为我在第二张卡中使用第一个构造器创建了一张新卡。有没有办法避免这样的情况,这样我就不会有两个单独的对象?如果可能的话,我想找到一种只使用一个构造函数的方法。以下是我的课程:

卡片爪哇:

package com.spdesigns.dokkancardspreview.model;

import javafx.scene.image.Image;

public class Card {

private String mName;
private String mDescription;
private Image mMainImage;
private Image mSecondaryImage;
private String mMainImagePath;
private String mSecondaryImagePath;

public Card(String name, String description, Image mainImage, Image secondaryImage) {
    mName = name;
    mDescription = description;
    mMainImage = mainImage;
    mSecondaryImage = secondaryImage;
}

public Card(String name, String description , String mainImagePath, String secondaryImagePath) {
   Card newCardToAdd =  new Card(name,description,new Image(mainImagePath),new Image(secondaryImagePath));
}

@Override
public String toString() {
    return mName + " | " + mDescription;
}

public Image getmMainImage() {
    return mMainImage;
}

public Image getmSecondaryImage() {
    return mSecondaryImage;
}

public String getName() {
    return mName;
}

public String getDescription() {
    return mDescription;
}
}

home.java:

package com.spdesigns.dokkancardspreview.controllers;

import com.spdesigns.dokkancardspreview.model.Card;

import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

import java.io.*;
import java.util.List;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;

public class home implements Initializable {

private Card hit = new Card("Hit","Expanding Possibility",
        new Image("/images/hit_main.jpg") , new Image("/images/hit_secondary.jpg"));

private Card goku = new Card("Goku SSJ3","Everlasting legend",
        new Image("/images/gokussj3_main.jpg") , new Image("/images/gokussj3_secondary.jpg"));

private boolean clickedAgain = false;

@FXML
private Button arrowButton;
@FXML
private ImageView imageView;

@FXML
private ImageView arrow;

@FXML
private ListView listView;

protected List<Card> testingList = new ArrayList<Card>();

    protected ListProperty<Card> listProperty = new SimpleListProperty<Card>();


@Override
public void initialize(URL location, ResourceBundle resources) {
    addCard(hit);
    addCard(goku);
    //testingList.add("test2");

    listView.itemsProperty().bind(listProperty);
    // wrapping our list in an observable list and then pass that observableList to the ListProperty isntance
    listProperty.set(FXCollections.observableArrayList(testingList));

    // Handle listView selection changes
    listView.getSelectionModel().selectedItemProperty().addListener(((observable, oldValue, newValue) -> {
        Card currentlySelectedCard = listProperty.get(listView.getSelectionModel().getSelectedIndex());
        System.out.printf("ListView item clicked! Value retrieved: %s\n", currentlySelectedCard);
        imageView.setImage(new Image(currentlySelectedCard.getmMainImage().impl_getUrl()));
        arrow.setVisible(true);
        arrowButton.setVisible(true);
    }));

    arrow.translateYProperty().set(283f);
    arrowButton.translateYProperty().set(283f);
    arrow.setRotate(180);
    arrow.setVisible(false);
    arrowButton.setVisible(false);
}

public void handleShowDetails(ActionEvent actionEvent) {
    System.out.println("Button Clicked!");
    Card currentlySelectedCard = listProperty.get(listView.getSelectionModel().getSelectedIndex());
    if(clickedAgain) {
        imageView.setImage(new Image(currentlySelectedCard.getmMainImage().impl_getUrl()));
        arrow.setRotate(180);
        clickedAgain = false;
    } else {
        imageView.setImage(new Image(currentlySelectedCard.getmSecondaryImage().impl_getUrl()));
        arrow.setRotate(360);
        clickedAgain = true;
    }
}

// Saving
public void exportTo(String fileName) {
    try(
            FileOutputStream fos = new FileOutputStream(fileName);
            PrintWriter writer = new PrintWriter(fos);
    ){
        for(int i =0;i<testingList.size()-1;i++) {
            writer.printf("%s|%s|%s|%s\n",testingList.get(i).getName(),testingList.get(i).getDescription(),
                    testingList.get(i).getmMainImage().impl_getUrl(),testingList.get(i).getmSecondaryImage().impl_getUrl());
            System.out.println(testingList.get(i).toString());
        }
    } catch (IOException ioe) {
        System.out.printf("Problem saving: %s/n", fileName);
        ioe.printStackTrace();
    }
}

// Loading
public void importFrom(String fileName) {
    try(
            FileInputStream fis = new FileInputStream(fileName);
            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
    ){
        String line;
        while((line = reader.readLine()) != null) {
            String[] args = line.split("\\|");
            this.addCard(new Card(args[0],args[1],args[2],args[3]));
        }
    } catch (IOException ioe) {
        System.out.printf("Problem loading: %S\n" , fileName);
        ioe.printStackTrace();
    }
    int i = 0;
    for (Card card : testingList) {
        System.out.printf("%s loaded\n",testingList.get(i).toString());
        i++;
    }
    System.out.println("Loading Successful!");
}

public void addCard(Card card) {
    testingList.add(card);
}

// DEBUG purposes
public void printTestingList() {
    for (Card card : testingList) {
        System.out.println(card.toString());
    }
}
}

主. java:

package com.spdesigns.dokkancardspreview;

import com.spdesigns.dokkancardspreview.controllers.home;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.File;

public class Main extends Application {

private home controller;
private File file = new File("CardsCollection.txt");

@Override
public void start(Stage primaryStage) throws Exception{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/home.fxml"));
    Parent root = loader.load();
    controller = loader.getController();
    primaryStage.setTitle("Dokkan Battle Card Preview");
    primaryStage.setScene(new Scene(root, 900, 700));
    primaryStage.setResizable(false);
    // Loading cards
    primaryStage.show();
    try {
        if(!file.exists()) {
            file.createNewFile();
        }
        controller.importFrom("CardsCollection.txt");
    } catch (NullPointerException npe) {
        System.out.println("Error loading file!");
        npe.printStackTrace();
    }
}

@Override
public void stop() {
    System.out.println("App is closing!");
    // Saving before exiting
    try {
        controller.exportTo("CardsCollection.txt");
    } catch (NullPointerException npe) {
        System.out.println("Problem saving file!");
        npe.printStackTrace();
    }
   // controller.printTestingList();
}

public static void main(String[] args) {
    launch(args);
}
}

共有3个答案

云长恨
2023-03-14

如果不需要将Images直接传递给类(仅图像路径),那么一个构造函数就足够了:

public Card(String name, String description, 
               String mainImagePath, String secondaryImagePath) {
    mName = name;
    mDescription = description;
    mMainImagePath = mainImagePath;
    mSecondaryImagePath = secondaryImagePath;
    mMainImage = new Image(mainImagePath);
    mSecondaryImage = new Image(secondaryImagePath);
}
扈韬
2023-03-14

您的代码存在以下问题:

public Card(String name, String description , String mainImagePath, String secondaryImagePath) {
   Card newCardToAdd =  new Card(name,description,new Image(mainImagePath),new Image(secondaryImagePath));
}

如您所见,您在那里创建了一个新卡newCardToAdd,将新实例初始化为完全错误的...

在这种情况下,你要做的是从另一个构造函数调用一个构造函数。。。在你的例子中,你的两个同构体应该是这样的:

public Card(String name, String description, Image mainImage, Image secondaryImage) {
    mName = name;
    mDescription = description;
    mMainImage = mainImage;
    mSecondaryImage = secondaryImage;
}

public Card(String name, String description, String mainImagePath, String secondaryImagePath) {
    this(name, description, new Image(mainImagePath), new Image(secondaryImagePath));
}
令狐经武
2023-03-14

改变

public Card(String name, String description , String mainImagePath, String secondaryImagePath) {
   Card newCardToAdd =  new Card(name,description,new Image(mainImagePath),new Image(secondaryImagePath));
}

public Card(String name, String description , String mainImagePath, String secondaryImagePath) {
   this(name,description,new Image(mainImagePath),new Image(secondaryImagePath));
}
 类似资料:
  • 我编写了以下代码和驱动程序,但我不知道如何使用两个构造函数创建银行账户对象。一个构造函数获取初始余额,第二个构造函数在没有钱的情况下开设账户。此外,Account tBalance是否应该包括有效性检查? 或者,我可以执行以下操作: 将费用作为描述银行账户的一部分。根据需要更新BankAccount类。用户应该能够为每个帐户设置费用金额,并通过一种方法添加费用。向驱动程序添加代码以演示费用功能。(

  • 在ScalaMock的旧版本中,这段代码可以工作。在Scala2.12和Scalamock3.6中,我得到了一个NullPointerException,因为即使我创建了一个存根,它仍然在调用BrokenClass的构造函数的“s.length”行。所以它试图取消引用“s”,它是空的,因为我没有传递任何东西给它,因为我想要的只是一个存根,它在调用特定方法时返回一个特定值。 有没有一种方法可以在不调

  • 我的问题是关于OOP(C)中的构造函数。当我在一个类中将默认构造函数定义为private,并且在main中将该类的一个对象初始化为default时,就会出现默认构造函数不可访问的错误。这很好。但我也在Public部分中使用默认参数构造函数,当我再次在main中初始化对象时,就会出现对函数重载的不明确调用。所以我的问题是,如果不能从main访问私有构造函数,那么编译器应该调用公共部分中的构造函数,这

  • 在hibernate的xml方法中,创建hibernate SessionFactory对象时使用

  • @adilooze解决方案

  • 问题内容: 我一直认为无需调用构造函数即可创建对象。 但是,在 明智地 阅读《有效的Java 项目11:覆盖克隆》时 ,我发现了一条声明,指出 “没有调用构造函数”的规定太强了。行为良好的克隆方法可以调用构造函数来创建正在构建的克隆内部的对象。如果该类是最终的,则clone甚至可以返回由构造函数创建的对象。 有人可以向我解释一下吗? 问题答案: 我一直以为clone()会创建一个对象而不调用构造函