用Java打印到用户的正确方法是什么

时间:2016-07-13 22:34:35

标签: java class printing main

我的计算机科学老师告诉我,我不应该从getter等方法打印字符串,而且我应该从main方法打印到用户。我想知道我打印的地方是否重要,以及构建代码的正确方法是什么。

例如:

files = list.files(pattern="*.dta") 
dflist <- list()

for (i in 1:length(files)) {
  dflist[[i]] <- read.dta13(files[[i]], nonint.factors = TRUE)

  if(grepl("adjusted", files[[i]]) == TRUE) {
    dflist[[i]]$adjusted <- "yes"
  }
}

而不是我的老师说我应该写它

public class Main {
    public static void main(String[] args) throws IOException {
        Bank bank = new Bank(20);
        System.out.println(bank.getBalance());
    }
}

public class Bank {
    int balance;

    public Bank(int balance){
        this.balance = balance;
    }

    public String getBalance(){
        return "You have $" + this.balance;
    }
}

4 个答案:

答案 0 :(得分:4)

你的老师是对的。

您实际上并没有在getter中打印任何内容,只是因为您正在模糊数据类型。 balance帐户(实际上不是银行)可能是数字类型(intlong),而不是String

一般来说,让你的方法做正确的事。通过在getter中打印一些内容并返回可以进行调试,但一般情况下不可取。这就是你老师的意思。

编写具有良好定义和类型安全API的类非常有用,尤其是在Java中。

答案 1 :(得分:3)

你的老师是对的。

getBalance方法的目的是以应用程序的其他部分可以使用它的方式“获取”平衡。有很多方法可以使用余额,包括打印它(以各种方式/各种方式)将其添加到电子表格中,将其添加到总计等等。

如果你设计你的getBalance()方法来格式化和打印天平(到标准输出),那么所有其他的东西都需要其他方法......用于彼此的事情。

软件工程中有一个称为“separation of concerns”的原则。一个类(或更一般地说,一个模块)应该做它需要做的事情,并将其他东西留给classes方法的调用者。在这种情况下,我们正在谈论细粒度的SoC ......但这个原则也适用于这个层次。

答案 2 :(得分:0)

老师会给你写的版本对我来说更有意义。作为Java类的用户,我更喜欢将余额作为数字,然后以我希望的方式使用它。将数据显示为美元字符串显然是一个有效的用例,但不是我能想到的唯一用例。假设,作为您班级的客户,我想知道我的账户可以获得多少欧元,英镑或卢比,那么第二次实施将更适合我。

答案 3 :(得分:0)

您的老师可能建议银行不应该对如何将余额显示为字符串负责,因为使用银行的不同人可能希望以不同方式显示余额。

解决这个问题的一种方法是简单地按照教授的建议保留银行,然后在获得余额编号后以自己的方式格式化。

第二种方法是创建自己的格式化程序类,以您希望的方式格式化字符串:

public class Main2 
{     
    public Main2() {
        Bank bank = new Bank(20);
        System.out.println(BalanceFormat.formatBalance(bank.getBalance()));
    }

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

class Bank {
    private int balance;

    public Bank(int balance) {
        this.balance = balance;
    }

    public int getBalance() {
        return balance;
    }
}


class BalanceFormat 
{
    public static String formatBalance(int balance) {
        return ("Your balance is $" + balance);    
    }
}   

执行此操作的第三种方法是通过回调,这样您就可以告诉银行在维持其默认值时您希望它的行为方式。

public class Main 
{    
    public Main() 
    {
        Bank bank = new Bank(20);
        System.out.println(bank.getBalanceString());     
        Bank bank2 = new Bank(20, (balance) -> {
            return ("Your balance is: $" + balance);
        });
        System.out.println(bank2.getBalanceString());             
    }

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

    private class Bank 
    {
        int balance;
        BalanceStringCallback bankPrintBehavior = null;

        public Bank(int balance, BalanceStringCallback callback) 
        {
            this.bankPrintBehavior = callback;
            this.balance = balance;
        }

        public Bank(int balance) 
        {
            this.balance = balance;
        }

        public int getBalance() 
        {
            return this.balance;
        }

        public String getBalanceString() 
        {
            if (bankPrintBehavior == null) {
                return String.valueOf(balance);
            } else {
                return (bankPrintBehavior.callback(balance));
            }
        }
    }

    @FunctionalInterface
    private interface BalanceStringCallback 
    {
        abstract String callback(int balance);
    }    
}

还有其他方法,比如创建自己的Bank子类,并让它知道如何以您喜欢的方式进行格式化(虽然这会改变一个银行的行为更加困难,而第三种回调方式也允许您更改在飞行中的行为),但这三种方式首先浮现在脑海中。