是否可以创建一个 'super' 变量然后将其更改为 sub class 类型并能够访问 subclass 方法
Is it possible to Create a 'super' variable and then change it to a sub class type and be able to access the subclass methods
我想要的是能够使用超类创建一个变量,然后 'turn' 它稍后进入子类并且能够访问子类方法。它总是被定义为一个子类,我只是在定义时不知道是哪个子类。
class SuperClass {
//superclass methods
}
class SubClass1 extends SuperClass {
void subClass1method() {
//do something
}
}
class SubClass2 extends SuperClass {
void subClass2method() {
//do something different
}
}
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
a.subClass1Method(); //this is undefined it says
//a instanceof SubClass1 returns true which is what confused me
} else {
a = new SubClass2();
a.subClass2Method(); //this is undefined it says
}
}
}
我不是问它为什么这样做,而是解决它并获得我想要的结果的正确方法。
我查找了重复项,但很容易遗漏一个,所以请告诉我。
很简单。
如果您定义 class“SuperClass”的“a”,您只能访问“SuperClass”方法!
最终,您可以将抽象方法“subClass1method”和“subClass2method”添加到“SuperClass”并在 subclasses.
中实现它们
如果您无法控制源,那么除了转换(或 可能 使用适配器)之外,您无能为力。如果 instanceof
和投射声音在您的课程中很熟悉,那么这可能是您的教授所期望的。
以下是您的一些选择:
// to execute those subclass specific methods without casting..
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
SubClass1 subClass1 = new SubClass1();
subClass1.subClass1Method();
superClass = subClass1;
} else {
SubClass2 subClass2 = new SubClass2();
subClass2.subClass2Method();
superClass = subClass2;
}
// ... ...
}
// using instanceof and casting
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
superClass = new SubClass1();
} else {
superClass = new SubClass2();
}
// ... ... ...
if(superClass instanceof SubClass1) {
((SubClass1) superClass).subClass1Method();
} else if(superClass instanceof SubClass2) {
((SubClass2) superClass).subClass2Method();
}
}
以下是我在控制源时实现此目标的建议..
您可以使用组合为 class 提供不同的行为,而不是针对不同行为的新 class。请注意,如果您了解函数式接口和方法引用,这将特别方便。
public class SuperClass {
private MyBehavior behavior;
public void setBehavior(MyBehavior behavior) { this.behavior = behavior; }
public void doBehavior() { this.behavior.doBehavior(); }
}
public interface MyBehavior { public void doBehavior(); }
public class MyGoodBehavior implements MyBehavior {
@Override public void doBehavior() { System.out.print("good behavior"); }
}
public class MyBadBehavior implements MyBehavior {
@Override public void doBehavior() { System.out.print("bad behavior"); }
}
public static void main(String[] args) {
SuperClass a = new SuperClass();
a.setBehavior(new MyBadBehavior());
a.doBehavior();
}
当您执行 SuperClass a
时,您告诉编译器您打算将类型 SuperClass
的对象存储在变量 a
中。这意味着您也可以存储 SuperClass
的子 class,但是编译器只会将 a
视为类型 SuperClass
的对象,无论您是否存储子 SuperClass
类型。
在运行时没有对此进行检查,如果您设法编写从 a
上的子 class 调用方法的代码,它们将被调用。如果 a
不是那个特定的子 class 并且不实现被调用的方法,则会抛出异常。
但是你如何强制编译器接受 a
是 subclass 类型呢?铸件。您将 a
转换为 subclass,然后您可以访问 a
上 subclass 的方法。如果甚至无法将对象转换为子对象class,您会在编译时出错。
将您的 Main
class 更改为以下内容,它应该可以满足您的要求:
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
((SubClass1)a).subClass1Method(); // Casting 'a' as SubClass1
} else {
a = new SubClass2();
((SubClass2)a).subClass2Method(); // Casting 'a' as SubClass2
}
}
}
一些在编译时和运行时转换工作和不工作的例子:
class SuperClass { }
class SubClass1 extends SuperClass { }
class SubClass2 extends SuperClass { }
class Main {
public static void main(String... args) {
SuperClass a;
SubClass1 b;
SubClass2 c;
b = new SubClass1();
a = b; // autocast to SuperClass
a = new SubClass1();
b = a; // Compile error
b = (SubClass1) a; // explicit cast
c = new SubClass2();
method(b); // works
method(c); // compiles, but will throw exception at runtime inside method
}
private static void method(SuperClass object) {
SubClass1 b = (SubClass1) object; // allowed by compiler but will throw exception at runtime in the second call, method(c)
}
}
我想要的是能够使用超类创建一个变量,然后 'turn' 它稍后进入子类并且能够访问子类方法。它总是被定义为一个子类,我只是在定义时不知道是哪个子类。
class SuperClass {
//superclass methods
}
class SubClass1 extends SuperClass {
void subClass1method() {
//do something
}
}
class SubClass2 extends SuperClass {
void subClass2method() {
//do something different
}
}
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
a.subClass1Method(); //this is undefined it says
//a instanceof SubClass1 returns true which is what confused me
} else {
a = new SubClass2();
a.subClass2Method(); //this is undefined it says
}
}
}
我不是问它为什么这样做,而是解决它并获得我想要的结果的正确方法。
我查找了重复项,但很容易遗漏一个,所以请告诉我。
很简单。 如果您定义 class“SuperClass”的“a”,您只能访问“SuperClass”方法! 最终,您可以将抽象方法“subClass1method”和“subClass2method”添加到“SuperClass”并在 subclasses.
中实现它们如果您无法控制源,那么除了转换(或 可能 使用适配器)之外,您无能为力。如果 instanceof
和投射声音在您的课程中很熟悉,那么这可能是您的教授所期望的。
以下是您的一些选择:
// to execute those subclass specific methods without casting..
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
SubClass1 subClass1 = new SubClass1();
subClass1.subClass1Method();
superClass = subClass1;
} else {
SubClass2 subClass2 = new SubClass2();
subClass2.subClass2Method();
superClass = subClass2;
}
// ... ...
}
// using instanceof and casting
public static void main ( String [] args ) {
SuperClass superClass;
if (true /*some reson to be SubClass1*/) {
superClass = new SubClass1();
} else {
superClass = new SubClass2();
}
// ... ... ...
if(superClass instanceof SubClass1) {
((SubClass1) superClass).subClass1Method();
} else if(superClass instanceof SubClass2) {
((SubClass2) superClass).subClass2Method();
}
}
以下是我在控制源时实现此目标的建议..
您可以使用组合为 class 提供不同的行为,而不是针对不同行为的新 class。请注意,如果您了解函数式接口和方法引用,这将特别方便。
public class SuperClass {
private MyBehavior behavior;
public void setBehavior(MyBehavior behavior) { this.behavior = behavior; }
public void doBehavior() { this.behavior.doBehavior(); }
}
public interface MyBehavior { public void doBehavior(); }
public class MyGoodBehavior implements MyBehavior {
@Override public void doBehavior() { System.out.print("good behavior"); }
}
public class MyBadBehavior implements MyBehavior {
@Override public void doBehavior() { System.out.print("bad behavior"); }
}
public static void main(String[] args) {
SuperClass a = new SuperClass();
a.setBehavior(new MyBadBehavior());
a.doBehavior();
}
当您执行 SuperClass a
时,您告诉编译器您打算将类型 SuperClass
的对象存储在变量 a
中。这意味着您也可以存储 SuperClass
的子 class,但是编译器只会将 a
视为类型 SuperClass
的对象,无论您是否存储子 SuperClass
类型。
在运行时没有对此进行检查,如果您设法编写从 a
上的子 class 调用方法的代码,它们将被调用。如果 a
不是那个特定的子 class 并且不实现被调用的方法,则会抛出异常。
但是你如何强制编译器接受 a
是 subclass 类型呢?铸件。您将 a
转换为 subclass,然后您可以访问 a
上 subclass 的方法。如果甚至无法将对象转换为子对象class,您会在编译时出错。
将您的 Main
class 更改为以下内容,它应该可以满足您的要求:
class Main {
public static void main ( String [] args ) {
SuperClass a;
if (*some reson to be SubClass1*) {
a = new SubClass1();
((SubClass1)a).subClass1Method(); // Casting 'a' as SubClass1
} else {
a = new SubClass2();
((SubClass2)a).subClass2Method(); // Casting 'a' as SubClass2
}
}
}
一些在编译时和运行时转换工作和不工作的例子:
class SuperClass { }
class SubClass1 extends SuperClass { }
class SubClass2 extends SuperClass { }
class Main {
public static void main(String... args) {
SuperClass a;
SubClass1 b;
SubClass2 c;
b = new SubClass1();
a = b; // autocast to SuperClass
a = new SubClass1();
b = a; // Compile error
b = (SubClass1) a; // explicit cast
c = new SubClass2();
method(b); // works
method(c); // compiles, but will throw exception at runtime inside method
}
private static void method(SuperClass object) {
SubClass1 b = (SubClass1) object; // allowed by compiler but will throw exception at runtime in the second call, method(c)
}
}