有一些帖子与我的要求类似,但我只需要描述一个实现并获得澄清。
我对Java不太熟悉。我需要修改两个类类型的列表对象。该列表将始终包含一种类型或另一种类型的对象,而不是同时包含两种类型。这些类有一个共同的父类。我想编写一个方法,可以使用强制转换来处理任一类类型的对象列表。我做了一个原型,这就是我的想法。
public class Parent {
int x = 0;
}
public class Child1 extends Parent {
int y = 1;
}
public class Child2 extends Parent {
int z = 10;
}
import java.util.ArrayList;
import java.util.List;
public class CastTest {
List<? extends Parent> modifyValues (List<? extends Parent> list) {
int count = 1;
for (Parent p: list) {
p.x += count;
if (p instanceof Child1) {
Child1 c = (Child1)p;
c.y += count;
}
else if (p instanceof Child2) {
Child2 c = (Child2)p;
c.z += count;
}
++count;
}
return list;
}
void printValues (List<? extends Parent> list) {
for (Parent p: list) {
System.out.println("x:" + p.x);
if (p instanceof Child1) {
Child1 c = (Child1)p;
System.out.println("y:" + c.y);
}
else if (p instanceof Child2) {
Child2 c = (Child2)p;
System.out.println("z:" + c.z);
}
System.out.println("------------------------");
}
}
public static void main(String[] args) {
CastTest castTest = new CastTest();
System.out.println("-----------------Child 1-----------------");
List<Child1> childList1 = new ArrayList<>();
childList1.add(new Child1());
childList1.add(new Child1());
childList1.add(new Child1());
List<? extends Parent> listAfter1 = castTest.modifyValues(childList1);
castTest.printValues(listAfter1);
System.out.println("\n-----------------Child 2-----------------");
List<Child2> childList2 = new ArrayList<>();
childList2.add(new Child2());
childList2.add(new Child2());
childList2.add(new Child2());
List<? extends Parent> listAfter2 = castTest.modifyValues(childList2);
castTest.printValues(listAfter2);
}
}
这似乎有效。
在进行实际工作之前,我想知道此实现/转换是否可能存在问题,以及这是否是正确的方法或是否有更好的方法。
我必须使用 Java 8。
您的解决方案工作正常,除非您开始添加 100 个以上的类。 然后,您必须为每个类实现不同的情况,因为即使某些类的变量名称(x,y,z)可能相同,必要的转换也会失败。
另一种可能性是使用反射。但这也需要对具有不同成员变量名称(x,y,z)的类进行不同的实现。 同样:可能,可行,但不是一个真正好的选择
在 Java 中做到这一点的最佳方法通常是让父类或接口声明一个函数(就像在您的例子中我们可以称之为
int getSpecialValue()
)来保证返回一个值。
这里将多个类和解决方案塞进一个类中:
package stackoverflow;
import java.util.List;
public class ForcedInheritance {
// parent class provides function and possibly un-used variable
static class NormalSolution {
static public class NormalParent {
int x = 0;
int specialValue = 0;
public void modifySpecialValue(final int pDelta) {
specialValue += pDelta;
}
public int getSpecialValue() {
return specialValue;
}
}
static public class Child1ofNormalParent extends NormalParent {
int y = 1;
}
static public class Child2ofNormalParent extends NormalParent {
int z = 10;
}
List<? extends NormalParent> modifyValues(final List<? extends NormalParent> list) {
int count = 1;
for (final NormalParent p : list) {
p.x += count;
p.modifySpecialValue(count);
++count;
}
return list;
}
void printValues(final List<? extends NormalParent> list) {
for (final NormalParent p : list) {
System.out.println("x:" + p.x);
System.out.println("special Value:" + p.getSpecialValue());
System.out.println("------------------------");
}
}
}
// parent class forces children to provide method and variable
static class AbstractSolution {
static public abstract class AbstractParent {
int x = 0;
public abstract void modifySpecialValue(final int pDelta);
public abstract int getSpecialValue();
}
static public class Child1ofAbstractParent extends AbstractParent {
int y = 1;
@Override public void modifySpecialValue(final int pDelta) {
y += pDelta;
}
@Override public int getSpecialValue() {
return y;
}
}
static public class Child2ofAbstractParent extends AbstractParent {
int z = 10;
@Override public void modifySpecialValue(final int pDelta) {
z += pDelta;
}
@Override public int getSpecialValue() {
return z;
}
}
List<? extends AbstractParent> modifyValues(final List<? extends AbstractParent> list) {
int count = 1;
for (final AbstractParent p : list) {
p.x += count;
p.modifySpecialValue(count);
++count;
}
return list;
}
void printValues(final List<? extends AbstractParent> list) {
for (final AbstractParent p : list) {
System.out.println("x:" + p.x);
System.out.println("special value:" + p.getSpecialValue());
System.out.println("------------------------");
}
}
}
// parent implements interface, similar to 'NormalSolution'
static class InterfaceSolution1 {
public interface ParentInterface1 {
void modifySpecialValue(final int pDelta);
int getSpecialValue();
}
static public abstract class InterfacedParent1 implements ParentInterface1 {
int x = 0;
}
static public class Child1ofInterfacedParent1 extends InterfacedParent1 {
int y = 1;
@Override public void modifySpecialValue(final int pDelta) {
y += pDelta;
}
@Override public int getSpecialValue() {
return y;
}
}
static public class Child2ofInterfacedParent1 extends InterfacedParent1 {
int z = 10;
@Override public void modifySpecialValue(final int pDelta) {
z += pDelta;
}
@Override public int getSpecialValue() {
return z;
}
}
List<? extends InterfacedParent1> modifyValues(final List<? extends InterfacedParent1> list) {
int count = 1;
for (final InterfacedParent1 p : list) {
p.x += count;
p.modifySpecialValue(count);
++count;
}
return list;
}
void printValues(final List<? extends InterfacedParent1> list) {
for (final InterfacedParent1 p : list) {
System.out.println("x:" + p.x);
System.out.println("special value:" + p.getSpecialValue());
System.out.println("------------------------");
}
}
}
// each child implements interface on its own
static class InterfaceSolution2 {
public interface ParentInterface2 {
void modifySpecialValue(final int pDelta);
int getSpecialValue();
}
static public abstract class InterfacedParent2 {
int x = 0;
}
static public class Child1ofInterfacedParent2 extends InterfacedParent2 implements ParentInterface2 {
int y = 1;
@Override public void modifySpecialValue(final int pDelta) {
y += pDelta;
}
@Override public int getSpecialValue() {
return y;
}
}
static public class Child2ofInterfacedParent2 extends InterfacedParent2 implements ParentInterface2 {
int z = 10;
@Override public void modifySpecialValue(final int pDelta) {
z += pDelta;
}
@Override public int getSpecialValue() {
return z;
}
}
List<? extends ParentInterface2> modifyValues(final List<? extends ParentInterface2> list) {
int count = 1;
for (final ParentInterface2 p : list) {
// p.x += count; // not possible here
p.modifySpecialValue(count);
++count;
}
return list;
}
void printValues(final List<? extends ParentInterface2> list) {
for (final ParentInterface2 p : list) {
// System.out.println("x:" + p.x); not possible here
System.out.println("special value:" + p.getSpecialValue());
System.out.println("------------------------");
}
}
}
}