[英]Avoid type casting
I have an empty interface called Data
which is implemented by classes DataOne
and DataTwo
. 我有一个称为Data
的空接口,该接口由DataOne
和DataTwo
类实现。
I then have a class called DataHolder
which contains a Data
object. 然后,我有一个名为DataHolder
的类,其中包含一个Data
对象。
It looks something like this: 看起来像这样:
public class DataHolder() {
public Data data;
}
public class DataOne() {
public int importantData;
public int getImportantData() {
return importantData;
}
public int setImportantData(int importantData) {
this.importantData = importantData;
}
}
public class DataTwo() {
public int notSoImportantData;
}
Let's say theres a function which takes a DataHolder
object and does some operation on the importantData integer. 假设有一个函数接受DataHolder
对象并对重要数据整数进行一些操作。
public void calculateImportantData(DataHolder dh) {
int importantData = 1234567890;
dh.data.setImportantData(importantData);
}
How can I be sure that the DataHolder
contains a DataOne
object, without typecasting? 我如何确定DataHolder
包含一个DataOne
对象,而不进行类型转换?
How about: 怎么样:
public class DataHolder<T extends Data> {
public T data;
}
and in your code you will have: 在您的代码中,您将拥有:
public void calculateImportantData(DataHolder<DataOne> dh) {
int importantData = 1234567890;
dh.data.setImportantData(importantData);
}
and I assume you meant DataOne and DataTwo to implement Data. 我假设您的意思是DataOne和DataTwo实现数据。
first of all , I tweaked your code a little bit , 首先,我对您的代码进行了一些调整,
1- I created an Interface , Data , containing some random method someMethod() : 1-我创建了一个接口Data,其中包含一些随机方法someMethod():
package main.interfaces;
public interface Data {
int myData = 0;
public void someMethod();
}
2- then , I created 2 classes called DataOne and DataTwo : Class DataOne: ( notice how i added the important business method setImportantData() here , this provides total Encapsulation of your work). 2-然后,我创建了两个名为DataOne和DataTwo的类:DataOne类:(请注意,我在这里如何添加重要的业务方法setImportantData(),这提供了您工作的全部封装 )。
package main;
import main.interfaces.Data;
public class DataOne implements Data{
public int importantData;
public int getImportantData() {
return importantData;
}
public void setImportantData(int importantData) {
this.importantData = importantData;
}
@Override
public void someMethod() {
System.out.println("here in DataOne!... ");
}
public void calculateImportantData(int importantData) {
// int importantData = 1234567890;
setImportantData(importantData);
}
}
Class DataTwo: 类数据二:
package main;
import main.interfaces.Data;
public class DataTwo implements Data{
public int notSoImportantData;
@Override
public void someMethod() {
System.out.println("here in DataTwo!...");
}
public void calculateUsualData(DataTwo d2) {
d2.someMethod();
}
} }
after that , using Factory Design Pattern ... I created this DataFactory class: 之后,使用Factory Design Pattern ...创建了这个DataFactory类:
package main.factory;
import main.DataOne;
import main.DataTwo;
import main.interfaces.Data;
public class DataFactory {
public static Data getData(String dataType){
if(dataType == null){
return null;
}
if(dataType.equalsIgnoreCase("DATAONE")){
return new DataOne();
} else if(dataType.equalsIgnoreCase("DATATWO")){
return new DataTwo();
}
return null;
}
}
now , back to your problem solution , I used DataHolder , encapsulating DataFactory here: 现在,回到您的问题解决方案中,我使用了DataHolder,将DataFactory封装在这里:
package main.holder;
import main.factory.DataFactory;
import main.interfaces.Data;
public class DataHolder {
Data data;
public DataHolder(String dataType){
data = DataFactory.getData(dataType);
}
public Data getData(){
return data;
}
}
now , try to run the application , I added some comments that will appear on your console , and I hope they will be helpful :) 现在,尝试运行该应用程序,我添加了一些注释,这些注释将出现在您的控制台上,希望对您有所帮助:)
package main.run;
import main.DataOne;
import main.DataTwo;
import main.holder.DataHolder;
import main.interfaces.Data;
public class main {
public static void main(String[] args) {
// lets assume user of the method passed a DataOne Object, you can
// manage it by changing the value of flag string
String flag = "DataOne";
DataHolder dataHolder = new DataHolder(flag);
if (dataHolder.getData() instanceof DataOne) {
System.out
.println("you have a DataOne object , but a Data reference");
System.out
.println("/nso , you need to create a 'reference' to DataOne to work on that object ...");
} else if (dataHolder.getData() instanceof DataTwo) {
System.out
.println("you have a DataTwo object , but a Data reference");
} else {
System.out
.println("you dont have a DataOne nor DataTwo references , it is a "
+ dataHolder.getData().getClass() + " object!");
}
System.out
.println("in order for the compiler to pass the following test , you must cast he RHS ( right hand side ) to match the LHS (left hand side)");
// in order for the compiler to pass the following test , you must cast
// the RHS ( right hand side ) to match the LHS (left hand side)
DataOne d1 = (DataOne) dataHolder.getData();
// in case you wanted to test DataTwo scenario
//DataTwo d2 = (DataTwo) dataHolder.getData();
System.out.println("if you didnt do that , you can make it a Data Object , but you will not be able to access the method 'getImportantData()' created in DataOne");
Data data = dataHolder.getData();
}
}
(note , here the program structure is : you select the type of the data before you start the application , stored in the "flag" variable inside the main method. after that , a call to DataHolder method will be made , after that , you can check the returned object and check if it is what u specified earlier. if you want it to be a little complicated , you can pass the object type in the DataHolder's constructor , and do the check from there , I didn't want to do it just for simplicity. Good Luck) (请注意,这里的程序结构是:在启动应用程序之前,选择数据的类型,将其存储在main方法中的“ flag”变量中。此后,将调用DataHolder方法,之后,您将可以检查返回的对象并检查它是否是您先前指定的对象。如果您希望它有点复杂,可以在DataHolder的构造函数中传递对象类型,然后从那里进行检查,我不想这样做只是为了简单起见。祝您好运)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.