我有一个超类和子类,我希望能够根据是否为超类实例或子类实例调用该方法来调用方法的特定实现。我计划使用if
条件来使用Java中的instanceof
运算符进行检查。我想知道是否有任何其他方式(泛型,可能是?)比实现这个if
条件更好地实现这一点 - 无论如何这似乎并不整齐。此外,通过这种方法,我不得不进行不安全的类型转换当我必须将obj
从SuperClass
类型转换为SubClass
类型时。请建议。
void doSomething (SuperClass obj) {
// Works the same way for super and sub class
int p = obj.getX1(obj);
int q = obj.getX2(obj);
int implementationSpecificVariable;
// choose behavior based on the actual class
if (obj instanceof SuperClass) {
implementationSpecificVariable = doForSuper(obj);
} else if (obj instanceof SubClass) {
implementationSpecificVariable = doForSub((SubClass) obj);
}
}
答案 0 :(得分:2)
使用OOP!
class SuperClass {
public void doSomething() { /* implementation for SuperClass */ }
}
class SubClass extends SuperClass {
@Override
public void doSomething() { /* implementation for SubClass */ }
}
现在,每当您引用SuperClass
或SubClass
的实例时,在其上调用doSomething
将调用第一个或第二个实现:
SuperClass obj = ...; // create instance of SuperClass or SubClass
obj.doSomething();
答案 1 :(得分:1)
Polymorphism是面向对象编程(OOP)的一个特性,它允许您为对象的各个子节点提供不同的实现。在编写代码时,你应该尽可能avoid instance of and downcasting,而不是使用多态。
例如:
class Parent {
public void method() {
System.out.println("In the Parent");
}
}
class ChildA extends Parent {
public void method() {
System.out.println("In Child A");
}
}
class ChildB extends Parent {
//no method
}
class Test {
public static void main(String[] args) {
Parent parent = new Parent();
Parent childA = new ChildA();
Parent childB = new ChildB();
ChildA anotherChildA = new ChildA();
ChildB anotherChildB = new ChildB();
parent.method(); //In the Parent
childA.method(); //In Child A
childB.method(); //In the Parent
anotherChildA.method(); //In Child A
anotherChildB.method(); //In the Parent
}
}
如您所见,执行由实例类型决定,而不是引用类型。因此,在您的示例中,您将在父级和每个子级中实现doFor()
方法。然后在父母(或其他类)doSomething()
中,您只需拨打this.doFor()
而不是if / else语句。
答案 2 :(得分:0)
您可以使用Interfaces或抽象类的概念。在类中实现的接口将允许您完全不同地处理和实现相同的名称功能,我认为它更适合您的情况。
搜索Java中的接口,以及有关接口和抽象类的差异,总有一天它们肯定会非常方便:)
答案 3 :(得分:0)
您所描述的内容称为“Strategy Pattern”,这基本上意味着您在运行时选择了所需的行为。 Here是如何使用接口实现模式的示例:
public enum ShippingMethod {
FIRST_CLASS {
public double getShippingCost(double weightInPounds, double distanceInMiles) {
// Calculate the shipping cost based on USPS First class mail table
}
},
FED_EX {
public double getShippingCost(double weightInPounds, double distanceInMiles) {
// Calculate the shipping cost based on FedEx shipping
}
},
UPS {
public double getShippingCost(double weightInPounds, double distanceInMiles) {
// Calculate the shipping cost based on UPS table
}
};
public abstract double getShippingCost(double weightInPounds, double distanceInMiles);
};
public class SuperClass {
public ShippingMethod getShippingMethod() {
return ShippingMethod.FIRST_CLASS;
}
}
public class SubClass {
public ShippingMethod getShippingMethod() {
return ShippingMethod.FED_EX;
}
}
public class SubSubClass {
public ShippingMethod getShippingMethod() {
return ShippingMethod.UPS;
}
}
public class ShippingService {
public void shipOrder(SuperClass item) {
double shippingCost = item.getShippingMethod().getShippingCost();
}
// or if you wanted to keep the service logic completely in the service, you could pass the service into the enum method call and have the strategy pick which method to execute
double shippingCost = item.getShippingMethod().getShippingCost(this);
}