Java变量值未传递给新类

时间:2015-05-06 02:14:12

标签: java

我终于开始自己开始,而不是在线跟踪课程,并试图自己创造一些东西,它只是一个简单的基于文本的地牢类型的游戏。

然而,当我将新值从一个类传递到另一个类时,我知道我搞砸了,我尝试将值设置为传递给另一个类的类

package com.company;

import java.util.Random;
import java.util.Scanner;



public class CharBuilder {
static public Random randNum = new Random();
static public Scanner sc = new Scanner(System.in);

 private String mCharacterName;
 private int mStrength = 6;
 private int mIntelligence = 6;
 private int mConstitution = 6;
 private int mDexterity = 6;
 private int mHitPoints = 40;
 private int mManaPoints = 40;
 private String mCharClass;
 private CharBuilder hero;




public CharBuilder(String charClass,int str, int intl, int con, int dex, int hp, int mp) {
    mCharClass = charClass;
    mStrength = str;
    mIntelligence = intl;
    mConstitution = con;
    mDexterity = dex;
    mHitPoints = hp;
    mManaPoints = mp;

}

public CharBuilder() {

}

public CharBuilder(String charClass) {
    mCharClass = charClass;

}



public void characterNameCreator() {

    System.out.println("Greetings, what is your name adventurer? ");
    mCharacterName = sc.nextLine();
    System.out.printf("I see, so your name is %s very well, very well \n", mCharacterName);
}

public void createHero() {
    hero = new  CharBuilder(mCharClass,mStrength,mIntelligence,mConstitution,mDexterity,mHitPoints,mManaPoints);


String acceptedAnswers = "warrior wizard thief";

    System.out.printf("%s would you say you are more of a warrior, wizard or more of the thievery type \n", mCharacterName);
    String classAnswer = sc.nextLine();
    boolean isAcceptableClass = classAnswer.contains(acceptedAnswers);
    do  {
        if (classAnswer.equalsIgnoreCase("warrior")) {
            mCharClass = "warrior";
            hero.setStr(mStrength + 3);
            hero.setIntelligence(mIntelligence - 1);
            hero.setmConstitution(mConstitution + 4);
            hero.setmDexterity(mDexterity + 1);
            hero.setHitPoints(mHitPoints + 20);
            hero.setManaPoints(mManaPoints - 10);
        } else if (classAnswer.equalsIgnoreCase("Wizard")) {
            mCharClass = "wizard";
            hero.setStr(mStrength -1);
            hero.setIntelligence(mIntelligence + 3);
            hero.setmConstitution(mConstitution + 2);
            hero.setmDexterity(mDexterity);
            hero.setHitPoints(mHitPoints - 10);
            hero.setManaPoints(mManaPoints + 30);
        } else if (classAnswer.equalsIgnoreCase("thief") || classAnswer.equalsIgnoreCase("thievery")) {
            mCharClass = "thief";
            hero.setStr(mStrength + 2);
            hero.setIntelligence(mIntelligence + 1);
            hero.setmConstitution(mConstitution + 1);
            hero.setmDexterity( mDexterity + 5);
            hero.setHitPoints(mHitPoints + 10);
            hero.setManaPoints(mManaPoints + 10);
        } else {
            System.out.println("I'm sorry, that is not an acceptable class, please pick warrior, wizard, or thief");
            createHero();
        }
    }while (isAcceptableClass);

}



public int getStrength() {
    return mStrength;
}
public  int getIntelligence() {
    return mIntelligence;
}
public int getConsitution() {
    return mConstitution;
}
public int getDex() {
    return mDexterity;
}
public int getHP() {
    return mHitPoints;
}
public int getMP() {
    return mManaPoints;
}
public CharBuilder getHero() {
    return hero;
}


public void setStr(int str) {
    mStrength = str;

}
public void setIntelligence(int intl) {
    mIntelligence = intl;
}
public void setmConstitution(int con) {
    mConstitution = con;
}
public void setmDexterity(int dex) {
    mDexterity = dex;
}
public void setHitPoints( int hitPoints) {
    mHitPoints = hitPoints;
}
public void setManaPoints( int manaPoints) {
    mManaPoints = manaPoints;
}
public void setmCharClass(String charClass) {
    mCharClass = charClass;
}







}

和我试图将变量传递给的类似乎没有得到任何东西,因为它给了我一个nullPointerException所以我知道当我要求它时没有任何价值它,我已经把下面的课程包括在内了,

package com.company;

import java.util.List;
import java.util.Random;
import java.util.Scanner;



public class Combat   {
    Scanner sc = CharBuilder.sc;
    Random randNum = CharBuilder.randNum;

    List<Enemy> enemyList = new Enemy().createList();
    Enemy enemy = enemyList.get(randNum.nextInt(enemyList.size()));
    CharBuilder character = new CharBuilder().getHero();
    int charStrength = character.getStrength();
    int charHp = character.getHP();
    int enemyHp = enemy.getHP();
    int enemyStr =enemy.getStr();
    String enemyName = enemy.getName();


    public void initiateCombat() {


        System.out.printf("A %s appears, it has %d hitpoints, and it's strength is %s \n", enemyName, enemyHp, enemyStr);
    }
    public void playersTurn() {
        System.out.println("It is your turn, your available actions are attack, or use a skill");
        String actionAnswer = sc.nextLine();
        if (actionAnswer.equalsIgnoreCase("attack")) {
            enemyHp -= charStrength;
            System.out.printf("You attack the enemy, doing %s damage, the enemy currently has %s hp left \n", charStrength,
                    enemyHp);

        }


        else {
            System.out.println("Sorry, please choose attack or skill ");
            playersTurn();
        }
    }
    public void enemyTurn() {
        charHp -= enemyStr;
        System.out.printf("It is the enemy's turn, it attacks doing %s damage, your current hp is %s \n", enemyStr, charHp);
    }
    public void combat() {
        while(enemyHp >= 0 && charHp >= 0) {
            initiateCombat();
            playersTurn();
            if (enemyHp <= 0) {
                System.out.println("You have defeated the enemy, congratulations");
                break;

            }
            enemyTurn();
        }
    }
}

任何关于我做错事的新人的提示,以及我如何能够获得这些价值?我知道我可以宣布英雄是静态的,但有更好的方法吗?

我在第一个可能的区域获得NullPointerException,他们试图从CharBuilder类中提取数据。这是

int charStrength = character.getStrength();

4 个答案:

答案 0 :(得分:1)

在您的构造函数中调用createHero()之前,您需要在CharBuilder上致电getHero()

答案 1 :(得分:1)

让我们看看为什么你有NPE问题:

看看这里

public CharBuilder() {

}

第一个构造函数是默认构造函数。它只初始化最小值,并允许用户使用getter和setter设置其余部分。

CharBuilder character = new CharBuilder().getHero();
some setters is missing here?
int charStrength = character.getStrength();

正如您在代码中看到的那样,您没有在病房后设置任何内容

此外,定义默认构造函数有三个常见原因:

  
      
  1. 使用默认值构建对象。
  2.   
  3. 初始化在初始化过程中不需要参数的对象。
  4.   
  5. 重新定义构造函数的范围。使构造函数私有将阻止除了类本身之外的任何人构造一个   对象。
  6.   

如果要确保创建的任何实例始终有效并且始终初始化任何成员变量,那么您将定义初始化所有必需成员变量的构造函数。

在您的情况下,您可以在createHero之前使用getHero功能,因为createHero会设置值。

<强>建议

Plaese看一下构建器模式来设计更好的类

More Info About Builder Pattern

答案 2 :(得分:1)

你的代码应该是,

/**
 *  Main function to register all of the plugin settings
 *
 * @since 1.0.0
 */
function sc_register_settings() {

    global $sc_options;

    $sc_options = array();

    $sc_settings = array(

        /* Default Settings */

        'default' => array(
            'note' => array(
                'id'   => 'settings_note',
                'name' => '',
                'desc' => sprintf( '<a href="%s" target="_blank">%s</a>', sc_ga_campaign_url( SC_WEBSITE_BASE_URL . 'docs/shortcodes/stripe-checkout/', 'stripe_checkout', 'settings', 'docs' ), __( 'See shortcode options and examples', 'sc' ) ) . ' ' .
                          __( 'for', 'sc' ) . ' ' . Stripe_Checkout::get_plugin_title() . '<br/>' .
                          '<p class="description">' . __( 'Shortcode attributes take precedence and will always override site-wide default settings.', 'sc' ) . '</p>',
                'type' => 'section'
            ),
            'name' => array(
                'id'   => 'name',
                'name' => __( 'Site Name', 'sc' ),
                'desc' => __( 'The name of your store or website. Defaults to Site Name.' , 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'currency' => array(
                'id'   => 'currency',
                'name' => __( 'Currency Code', 'sc' ),
                'desc' => __( 'Specify a currency using it\'s ', 'sc' ) .
                            sprintf( '<a href="%s" target="_blank">%s</a>', 'https://support.stripe.com/questions/which-currencies-does-stripe-support', __( '3-letter ISO Code', 'sc' ) ) . '. ' .
                            __( 'Defaults to USD.', 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'image_url' => array(
                'id'   => 'image_url',
                'name' => __( 'Image URL', 'sc' ),
                'desc' => __( 'A URL pointing to a square image of your brand or product. The recommended minimum size is 128x128px.' , 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'checkout_button_label' => array(
                'id'   => 'checkout_button_label',
                'name' => __( 'Checkout Button Label', 'sc' ),
                'desc' => __( 'The label of the payment button in the checkout form. You can use {{amount}} to display the amount.' , 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'payment_button_label' => array(
                'id'   => 'payment_button_label',
                'name' => __( 'Payment Button Label', 'sc' ),
                'desc' => __( 'Text to display on the default blue button that users click to initiate a checkout process.' , 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'success_redirect_url' => array(
                'id'   => 'success_redirect_url',
                'name' => __( 'Success Redirect URL', 'sc' ),
                'desc' => __( 'The URL that the user should be redirected to after a successful payment.' , 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'disable_success_message' => array(
                'id'   => 'disable_success_message',
                'name' => __( 'Disable Success Message', 'sc' ),
                'desc' => __( 'Disable default success message.', 'sc' ) . '<br/>' .
                          '<p class="description">' . __( 'Useful if you are redirecting to your own success page.', 'sc' ) . '</p>',
                'type' => 'checkbox'
            ),
            'failure_redirect_url' => array(
                'id'   => 'failure_redirect_url',
                'name' => __( 'Failure Redirect URL', 'sc' ),
                'desc' => __( 'The URL that the user should be redirected to after a failed payment.' , 'sc' ),
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'billing' => array(
                'id'   => 'billing',
                'name' => __( 'Enable Billing Address', 'sc' ),
                'desc' => __( 'Require the user to enter their billing address during checkout.', 'sc' ) . 
                        ( class_exists( 'Stripe_Checkout_Pro' ) ? '<br/><p class="description">' . __( 'See below if you also need to require a shipping address.', 'sc' ) . '</p>' : '' ),
                'type' => 'checkbox'
            ),
            'verify_zip' => array(
                'id'   => 'verify_zip',
                'name' => __( 'Verify Zip Code', 'sc' ),
                'desc' => __( 'Verifies the zip code of the card.', 'sc' ),
                'type' => 'checkbox'
            ),
            'enable_remember' => array(
                'id'   => 'enable_remember',
                'name' => __( 'Enable "Remember Me"', 'sc' ),
                'desc' => __( 'Adds a "Remember Me" option to the checkout form to allow the user to store their credit card for future use with other sites using Stripe. ', 'sc' ) .
                          sprintf( '<a href="%s" target="_blank">%s</a>', 'https://stripe.com/checkout/info', __( 'See how it works', 'sc' ) ),
                'type' => 'checkbox'
            ),
            'use_bitcoin' => array(
                'id'   => 'use_bitcoin',
                'name' => __( 'Enable Bitcoin', 'sc' ),
                'desc' => sprintf( __( 'Enable accepting <a href="%s" target="_blank">Bitcoin</a> as a payment option.', 'sc' ), 'https://stripe.com/docs/guides/bitcoin' ),
                'type' => 'checkbox'
            ),
            'disable_css' => array(
                'id'   => 'disable_css',
                'name' => __( 'Disable Plugin CSS', 'sc' ),
                'desc' => __( 'If this option is checked, this plugin\'s CSS file will not be referenced.', 'sc' ),
                'type' => 'checkbox'
            ),
            'always_enqueue' => array(
                'id'   => 'always_enqueue',
                'name' => __( 'Always Enqueue Scripts & Styles', 'sc' ),
                'desc' => __( 'Enqueue this plugin\'s scripts and styles on every post and page.', 'sc' ) . '<br/>' .
                          '<p class="description">' . __( 'Useful if using shortcodes in widgets or other non-standard locations.', 'sc' ) . '</p>',
                'type' => 'checkbox'
            ),
            'uninstall_save_settings' => array(
                'id'   => 'uninstall_save_settings',
                'name' => __( 'Save Settings', 'sc' ),
                'desc' => __( 'Save your settings when uninstalling this plugin.', 'sc' ) . '<br/>' .
                          '<p class="description">' . __( 'Useful when upgrading or re-installing.', 'sc' ) . '</p>',
                'type' => 'checkbox'
            )
        ),

        /* Keys settings */

        'keys' => array(
            'enable_live_key' => array(
                'id'   => 'enable_live_key',
                'name' => __( 'Test or Live Mode', 'sc' ),
                'desc' => '<p class="description">' . __( 'Toggle between using your Test or Live API keys.', 'sc' ) . '</p>',
                'type' => 'toggle_control'
            ),
            'note' => array(
                'id'   => 'api_key_note',
                'name' => '',
                'desc' => sprintf( '<a href="%s" target="_blank">%s</a>', 'https://dashboard.stripe.com/account/apikeys', __( 'Find your Stripe API keys here', 'sc' ) ),
                'type' => 'section'
            ),
            'test_secret_key' => array(
                'id'   => 'test_secret_key',
                'name' => __( 'Test Secret Key', 'sc' ),
                'desc' => '',
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'test_publish_key' => array(
                'id'   => 'test_publish_key',
                'name' => __( 'Test Publishable Key', 'sc' ),
                'desc' => '',
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'live_secret_key' => array(
                'id'   => 'live_secret_key',
                'name' => __( 'Live Secret Key', 'sc' ),
                'desc' => '',
                'type' => 'text',
                'size' => 'regular-text'
            ),
            'live_publish_key' => array(
                'id'   => 'live_publish_key',
                'name' => __( 'Live Publishable Key', 'sc' ),
                'desc' => '',
                'type' => 'text',
                'size' => 'regular-text'
            )
        )
    );

    $sc_settings = apply_filters( 'sc_settings', $sc_settings );

    $sc_settings_title = '';

    foreach( $sc_settings as $setting => $option ) {

        if( false == get_option( 'sc_settings_' . $setting ) ) {
            add_option( 'sc_settings_' . $setting );
        }

        add_settings_section(
            'sc_settings_' . $setting,
            apply_filters( 'sc_settings_' . $setting . '_title', $sc_settings_title ),
            '__return_false',
            'sc_settings_' . $setting
        );

        foreach ( $sc_settings[$setting] as $option ) {
            add_settings_field(
                'sc_settings_' . $setting . '[' . $option['id'] . ']',
                $option['name'],
                function_exists( 'sc_' . $option['type'] . '_callback' ) ? 'sc_' . $option['type'] . '_callback' : 'sc_missing_callback',
                'sc_settings_' . $setting,
                'sc_settings_' . $setting,
                sc_get_settings_field_args( $option, $setting )
            );
        }

        register_setting( 'sc_settings_' . $setting, 'sc_settings_' . $setting, 'sc_settings_sanitize' );

        $sc_options = array_merge( $sc_options, is_array( get_option( 'sc_settings_' . $setting ) ) ? get_option( 'sc_settings_' . $setting ) : array() );
    }

    update_option( 'sc_settings_master', $sc_options );

}
add_action( 'admin_init', 'sc_register_settings' );

原因是你需要执行createHero()才能初始化英雄对象。

进一步说明这一点,你在CharBuilder中初始化CharBuilder,当我们从面向对象的角度考虑时,这不是一个好习惯。一种替代方法是在此处使用singleton模式。

答案 3 :(得分:1)

正如已经指出的那样,您没有调用createHero,它会生成CharBuilder返回getHero的实例。因此返回null值。

这个问题似乎源于对建筑师应该做什么的误解。建筑商应该采取原材料并建造一些东西,它不应该自己返回它的副本。

例如......

public class CharBuilder {

    static public Random randNum = new Random();

    private String mCharacterName;
    private int mStrength = 6;
    private int mIntelligence = 6;
    private int mConstitution = 6;
    private int mDexterity = 6;
    private int mHitPoints = 40;
    private int mManaPoints = 40;
    private String mCharClass;
    private String classType;

    public Character createHero() {
        // Valid the properties you have been given...

        if ("warrior".equalsIgnoreCase(classType)) {
            mCharClass = "warrior";
            mStrength = mStrength + 3;
            mIntelligence = mIntelligence - 1;
            mConstitution = mConstitution + 4;
            mDexterity = mDexterity + 1;
            mHitPoints = mHitPoints + 20;
            mManaPoints = mManaPoints - 10;
        } else if ("Wizard".equalsIgnoreCase(classType)) {
            mCharClass = "wizard";
            mStrength = (mStrength - 1);
            mIntelligence = (mIntelligence + 3);
            mConstitution = (mConstitution + 2);
            mDexterity = (mDexterity);
            mHitPoints = (mHitPoints - 10);
            mManaPoints = (mManaPoints + 30);
        } else if ("thief".equalsIgnoreCase(classType) || "thievery".equalsIgnoreCase(classType)) {
            mCharClass = "thief";
            mStrength = (mStrength + 2);
            mIntelligence = (mIntelligence + 1);
            mConstitution = (mConstitution + 1);
            mDexterity = (mDexterity + 5);
            mHitPoints = (mHitPoints + 10);
            mManaPoints = (mManaPoints + 10);
        } else {
            throw new UnsupportedOperationException("Unknown class");
        }

        return new DefaultCharacter(mCharacterName, mStrength, mIntelligence, mConstitution, mDexterity, mHitPoints, mManaPoints, mCharClass);
    }

    public CharBuilder setCharacterName(String mCharacterName) {
        this.mCharacterName = mCharacterName;
        return this;
    }

    public CharBuilder setStrength(int mStrength) {
        this.mStrength = mStrength;
        return this;
    }

    public CharBuilder setIntelligence(int mIntelligence) {
        this.mIntelligence = mIntelligence;
        return this;
    }

    public CharBuilder setConstitution(int mConstitution) {
        this.mConstitution = mConstitution;
        return this;
    }

    public CharBuilder setDexterity(int mDexterity) {
        this.mDexterity = mDexterity;
        return this;
    }

    public CharBuilder setHitPoints(int mHitPoints) {
        this.mHitPoints = mHitPoints;
        return this;
    }

    public CharBuilder setManaPoints(int mManaPoints) {
        this.mManaPoints = mManaPoints;
        return this;
    }

    public CharBuilder setCharClass(String mCharClass) {
        this.mCharClass = mCharClass;
        return this;
    }

    public CharBuilder setClassType(String classType) {
        this.classType = classType;
        return this;
    }

}

您可以使用方法链来更容易调用,例如

Character character = new CharBuilder().
                setCharClass("Wizard").
                setCharacterName("Bob").
                setConstitution(10).
                setDexterity(10).
                setHitPoints(10).
                setIntelligence(10).
                setManaPoints(10).
                setStrength(10).
                createHero();

构建者不应该向用户提问,这些信息应该已经获得并且只是提供给构建者。你应该只调用你需要的方法来构建字符,所以上面例子中的许多方法可能会被省略而不支持默认值

Character character = new CharBuilder().
                setCharClass("Wizard").
                setCharacterName("Bob").
                createHero();

构建器应该验证它已经给出的属性,如果缺少一个或者必需的属性(如名称或类),则抛出Exception

我个人喜欢使用接口而不是实现,它允许您定义对象可以拥有的公共合同,例如......

public interface Character {
    public String getCharacterName();
    public int getStrength();
    public int getIntelligence();
    public int getConstitution();
    public int getDexterity();
    public int getHitPoints();
    public int getanaPoints();
    public String getCharClass();
}

可以用

包裹
public class DefaultCharacter implements Character {

    private final String mCharacterName;
    private final int mStrength;
    private final int mIntelligence;
    private final int mConstitution;
    private final int mDexterity;
    private final int mHitPoints;
    private final int mManaPoints;
    private final String mCharClass;

    public Character(String mCharacterName, int mStrength, int mIntelligence, int mConstitution, int mDexterity, int mHitPoints, int mManaPoints, String mCharClass) {
        this.mCharacterName = mCharacterName;
        this.mStrength = mStrength;
        this.mIntelligence = mIntelligence;
        this.mConstitution = mConstitution;
        this.mDexterity = mDexterity;
        this.mHitPoints = mHitPoints;
        this.mManaPoints = mManaPoints;
        this.mCharClass = mCharClass;
    }

    public String getCharacterName() {
        return mCharacterName;
    }

    public int getStrength() {
        return mStrength;
    }

    public int getIntelligence() {
        return mIntelligence;
    }

    public int getConstitution() {
        return mConstitution;
    }

    public int getDexterity() {
        return mDexterity;
    }

    public int getHitPoints() {
        return mHitPoints;
    }

    public int getManaPoints() {
        return mManaPoints;
    }

    public String getCharClass() {
        return mCharClass;
    }

}

现在,因为CharBuilder只会说它会返回Character,所以无论如何都可以更改物理实现

通过这种方式,很难遇到您遇到的问题,因为构建器将返回有效的Character或抛出Exception

详细了解Builder Pattern了解更多详情