Java多个具有不同数据类型的构造函数,可以吗,如何处理?

huangapple go评论60阅读模式
英文:

Java multiple constructors with different data types, oke or not, and how to handle?

问题

  1. 我应该如何存储 'val' 参数?使用 Object 似乎不是最佳方法。
  2. 如果我存储 'val',后来如何找回 'val' 是什么数据类型?

或者我完全错了,应该以完全不同的方式解决这个问题?

英文:

I have a class called 'Cell' in which I (think I) need multiple constructors

The goal is to add the cell's later to an excel sheet, when adding to an excel sheet you need to add what type of data to set the excell-cell to and therefor I want to retrieve the data type from the cell class

public Object val;

public Cell (BigDecimal val)
{
    this.val = val;
}

public Cell (String val)
{
    this.val = val;
}

public Cell (int val)
{
    this.val = val;
}

I have 2 questions

  1. How should I store the 'val' parameter, as Object just doesn't seem like the best way to do this?
  2. If I store 'val', how can I later find back what data type 'val' is/was ?

Or am I completely off here and is there a completely different way how I should approach this problem?

答案1

得分: 2

最佳方法是定义一个Cell接口,并实现多个扩展该接口的类。

public interface Cell {}

然后按照每种单元格类型创建实现类:

public class StringCell implements Cell {
    private String value;

    public StringCell(String value){
        this.value = value;
    }
    // ... 获取器和设置器等
}

您可以根据您的实现类的类型来确定值的类型。

英文:

Best way of achieving this is to define a Cell interface and implement multiple classes extending the interface.

public interface Cell {}

Followed by implementation class per cell type:

public class StringCell implements Cell {
    private String value;

    public StringCell(String value){
        this.value = value;
    }
    // ... getters and setters etc
}

You can later find out what type the value is, based on the type of your implementation class.

答案2

得分: 2

也许在你的情况下,Cell 太泛化了。例如,你可以考虑为 NumericCellStringCell 创建不同的类:

class NumericCell implements Cell {
    private BigDecimal val;

    public NumericCell(BigDecimal val) {
        this.val = val;
    }

    public NumericCell(int val) {
        this(BigDecimal.valueOf(val));
    }
}

class StringCell implements Cell {
    private String val;

    public StringCell(String val) {
        this.val = val;
    }
}

你可以将 Cell 保留为一个抽象类或接口,然后在那里放置你希望所有单元格执行的通用方法,例如:

interface Cell {
    String content();
}

现在,StringCell 可以实现这个方法并简单地返回 val,而 NumericCell 知道它是在 BigDecimal 上操作,因此可以执行一些格式化,例如只显示两位小数并四舍五入到最接近的整数:

@Override
public String content() {
    return val.setScale(2, RoundingMode.FLOOR).toString();
}

这被称为多态性,是面向对象编程中非常强大的工具。你可以在这里阅读更多关于它的信息:https://www.w3schools.com/java/java_polymorphism.asp

英文:

maybe Cell is too generic in your case. For example, you might consider having different classes for NumericCell and StringCell:

class NumericCell implements Cell {
	private BigDecimal val;

	public NumericCell (BigDecimal val) {
		this.val = val;
	}

	public NumericCell (int val) {
		this(BigDecimal.valueOf(val));
	}
}

class StringCell implements Cell {
	private String val;

	public StringCell (String val) {
		this.val = val;
	}
}

you can keep Cell as an abstract class or interface and put there the common methods you want all the cells to perform, for example

interface Cell {
    String content();
}

now StringCell can implement this and simply return val, while NumericCell knows it operates on a BigDecimal so it can perform some formatting, for example only display 2 decimals and rounding the number:

@Override
public String content() {
    return val.setScale(2, RoundingMode.FLOOR).toString();
}

This is called polymorphism and it is a very powerful tool in OOP. you can read more about it here: https://www.w3schools.com/java/java_polymorphism.asp

答案3

得分: 0

不要回答我要翻译的问题。\n\n\n这不是一个真正的好主意,如果您实际上需要对其执行特定操作或需要知道变量当前存储的确切数据类型,那么使用通用类型来存储任意数据。您可以采取一些方法来解决这个问题。一个想法是使用继承来创建您的类。即定义

public class StringCell extends Cell {
    public String val;

    public StringCell(String val) {
        this.val = val;
    }

    // getType() 和 getValue() 函数
    // 一些特定于 StringCell 的操作
}

然后,您可以将父类定义为抽象类并定义 getType()getValue() 函数。由于您使用不同的类型,我不会在父类中存储 val。然后,如果您需要在数据上执行特定函数,可以在子类中实现它(例如 addIntCell(IntCell c2) 等)。

这种方法还允许您处理字符串数据的任意字符串。如果您只执行数值操作,还可以进行类型转换,例如转换为 BigDecimal(因为它具有高分辨率),然后存储另一个变量 type。这可以是枚举值。然后,检索值的函数可以尊重 type 变量,并相应地获取输出。

重要提示:输出值必须是通用/兼容的。因此,即使您知道变量是字符串类型的,当该值可以从多个来源检索时(即在另一个实例上它是整数),您应该在某些情况下小心处理假设并进行一些合理性检查。特别是上面提到的 getValue 函数需要为所有子类返回相同的数据类型。

英文:

It is not really a good idea to do use generic types to store arbitrary data in a variable if you actually need to perform specific operations on it or need to know what exact data type the variable is currently storing.

You could do a few things to fix it. One idea: use inheritance for your class. I.e. define

public class StringCell extends Cell {
    public String val;

    public StringCell (String val) {
        this.val = val;
    }
    
    // getType() and getValue() function
    // some specific operations for StringCell
}

You could then make the parent class abstract and define a getType() and getValue() function. Since you are using different types, I would not store val in the parent class. Then, if you need specific functions on the data you implement it in the child classes (i.e. addIntCell(IntCell c2) and so on).

This approach lets you also handle arbitrary Strings for your String data. If you only do numeric operations you could also do a type conversion to e.g. BigDecimal (since it has high resolution) and then store another variable type. This can be a value from an Enum. Then, the functions to retrieve values can respect the type variable and get an output accordingly.

IMPORTANT: the output values must be generic/compatible. So even if you know that the variable is String-valued, you should be careful when this value can be retrieved from several sources (i.e. on another instance it yields an integer). So be careful about assumptions and stop for some sanity checks now and then. Specifically, the getValue function mentioned above needs to return the same data type for all subclasses.

huangapple
  • 本文由 发表于 2023年3月12日 19:50:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712907.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定