返回一个子类作为类型接口

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

Returning a subclass as type interface

问题

我遇到了一个关于我正在为作业编写的类的问题。我有一个接口,Person,它有3个抽象方法:getID、getFirstName和getLastName。这些方法返回字符串。我还有另一个叫做Employee的类,它实现了Person接口。我有一个静态方法,它接受一个来自文件的字符串行,并实例化一个新的Employee对象,然后将其作为Person返回。唯一的问题是Employee还有一个工资属性,而Person不能拥有这个属性,所以当我尝试操作新对象上的数据时,无法访问对象中的工资属性。我真的不知道有任何解决办法。如果你们中任何人对此有任何建议,我将不胜感激。以下是我用来创建列表的解析方法,以及我用来创建列表的流,我试图操作工资数据的流,还有接口。

public static Person parse(String s) {
    String[] empData = s.split(",");
    Employee hello = new Employee(empData[0], empData[1], empData[2], BigDecimal.valueOf(Double.parseDouble(empData[3])));
    
    return hello;
}
List<Person> stream = Files.lines(Paths.get(fileName))
    .map(Employee::parse)
    .collect(Collectors.toList());
DoubleSummaryStatistics total = stream.stream().mapToDouble((emp) -> Double.parseDouble(emp.salary.toString())).summaryStatistics();
System.out.println("Total average and the total number of employees:");
import java.math.BigDecimal;

public interface Person {
    public String getID();
    public String getFirstName();
    public String getLastName();
}
英文:

I am having a problem with a class I am writing for an assignment. I have an interface, Person, that has 3 abstract methods getID, getFirstName, and getLastName. These return Strings. I have another class called Employee which implements Person. I have a static method, which takes in a line from a file as a String and instantiates a new object of Employee then returns it as a Person. The only problem is that Employee also has an attribute called salary that Person cannot have, so later when I try to manipulate data on the new objects, I cannot access the salary attribute in the objects. I really don't know any way around this. If any of you can give me any suggestions on this, it would be greatly appreciated. Below you can find the parse method, and the stream I used to create the list, the stream where I attempted to manipulate the salary data, and the interface.

public static Person parse(String s) { 
    String[] empData = s.split(&quot;,&quot;); 
    Employee hello = new Employee(empData[0], empData[1], empData[2], BigDecimal.valueOf(Double.parseDouble(empData[3]))); 
		
    return hello;
}  
List&lt;Person&gt; stream = Files.lines(Paths.get(fileName)) 
	.map(Employee::parse)
	.collect(Collectors.toList()); 
DoubleSummaryStatistics total = stream.stream().mapToDouble((emp) -&gt; Double.parseDouble(emp.salary.toString())).summaryStatistics(); 
			System.out.println(&quot;Total average and the total number of employees:&quot;); 
import java.math.BigDecimal;

public interface Person {
	public String getID(); 
	public String getFirstName(); 
	public String getLastName();
}

答案1

得分: 3

> 接收来自文件的一行作为字符串,然后实例化一个新的 Employee 对象,并将其作为 Person 返回。

医生,我按这里会疼!

那好吧,那就别再这样做了。

改为返回 List&lt;Employee&gt;。返回 List&lt;Person&gt; 的整个要点在于你可以随时改变想法并返回非员工(你已经同意始终返回人,但不一定是员工),因此,javac 不会让你假设它们是员工。如果你想继续并假设:嘿,这些始终是员工,因此 'person.getSalary()' 总是合理的,那么……表达出来。

如果可以的话,你可以使用 instanceof 来检查一个人是否是员工,然后进行强制转换以获取工资:

double salary = p instanceof Employee ? ((Employee) p).getSalary() : 0.0;

从 Java 15 开始,你还可以这样写:

double salary = p instanceof Employee e ? e.getSalary() : 0.0;

这样看起来更加漂亮…

但这是一种非常不同类型的代码:这是在说:对于所有的人,_如果_他们是员工,就将他们的工资视为员工对象所说的。如果不是,则将它们视为 0。如果这正是你 想要 的,这段代码是有效的,但听起来更像是你感到困惑。你手头是一个人的列表,还是一个员工的列表,到底是哪个?

英文:

> which takes in a line from a file as a String and instantiates a new object of Employee then returns it as a Person.

Doctor, it hurts when I press here!

Well, stop doing that then.

Return this as a List&lt;Employee&gt; instead. The whole point of returning List&lt;Person&gt; is that you are free to change your mind later and return non-employees (you have signed up to always return persons, but not neccessarily employees), therefore, javac will not let you presume that they are employees. If you want to carry on and assume: Hey, these are always employees, therefore 'person.getSalary()' is always going to be sensible, then... say that.

If you can't, you can use instanceof to check if a person is an employee, and then cast to get the salary:

double salary = p instanceof Employee ? ((Employee) p).getSalary() : 0.0;

and starting in java15, you can write:

double salary = p instanceof Employee e ? e.getSalary() : 0.0;

which is a lot prettier...

but that's a very different kind of code: That's saying: For all persons, IF they are employee, consider their salary to be whatever the employee object says it is. If not, then count them at 0. If that's what you WANT, this code works, but it sounds more like you're confused. Do you have a list of persons, or a list of employees, which one is it?

huangapple
  • 本文由 发表于 2020年9月23日 21:31:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/64029150.html
匿名

发表评论

匿名网友

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

确定