[英]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
What I would like is to be able to create a variable with the superclass and then 'turn' it into the subclass later & be able to access the subClasses methods.我想要的是能够使用超类创建一个变量,然后稍后将其“转换”为子类并能够访问子类方法。 It will always be defined to a subclass I just don't know which when defining.
它总是被定义为一个子类,我只是在定义时不知道是哪个子类。
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
}
}
}
I am not asking why it does this but the correct way to work around it & get the results I want.我不是在问它为什么这样做,而是在问解决它并获得我想要的结果的正确方法。
I have looked for duplicates but could have easily missed one so please let me know.我一直在寻找重复的,但很容易错过一个,所以请告诉我。
When you don't have control of the source then there's not too much you can do besides casting (or possibly using adapters).当您无法控制源时,除了强制转换(或可能使用适配器)之外,您无能为力。 If
instanceof
and casting sound familiar from your lessons then that's probably what your prof is expecting.如果您的课程中
instanceof
和 cast 听起来很熟悉,那么这可能就是您的教授所期望的。
Here are some of your options:以下是您的一些选择:
// 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();
}
}
Below is my recommendation to achieve this goal when you have control of the source..以下是我的建议,以在您控制源代码时实现此目标。
Rather than a new class for different behaviors you could just use composition to provide different behaviors to the one class.而不是针对不同行为的新 class,您可以使用组合来为一个 class 提供不同的行为。 Note that this is especially convenient if you understand Functional Interfaces and Method References.
请注意,如果您了解功能接口和方法引用,这将特别方便。
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();
}
It's simple.这很简单。 If you define "a" of class "SuperClass" you can only access "SuperClass" methods.
如果您定义 class“SuperClass”的“a”,则只能访问“SuperClass”方法。 Eventually you could add abstract methods "subClass1method" and "subClass2method" to "SuperClass" and implement them in the subclasses.
最终,您可以将抽象方法“subClass1method”和“subClass2method”添加到“SuperClass”并在子类中实现它们。
When you do SuperClass a
you tell the compiler that you intend to store objects of type SuperClass
in the variable a
.当您执行
SuperClass a
时,您告诉编译器您打算将SuperClass
类型的对象存储在变量a
中。 It means that you can store subclasses of SuperClass
as well, but the compiler only sees a
as an object of type SuperClass
, regardless if you are storing a sub type.这意味着您也可以存储
SuperClass
的子类,但编译器仅将a
视为 SuperClass 类型的SuperClass
,无论您是否存储子类型。
At runtime there's no check for this, if you manage to write code that calls methods from a subclass on a
, they will be called.在运行时没有对此进行检查,如果您设法编写从 a 上
a
子类调用方法的代码,它们将被调用。 If a
is not of that particular sub class and don't implement the called method, an exception would be thrown.如果
a
不是那个特定的子 class 并且不实现被调用的方法,则会引发异常。
But how do you force the compiler to accept that a
is of the subclass type?但是如何强制编译器接受
a
是子类类型呢? Casting.铸件。 You cast
a
to the subclass, then you can access methods from subclass on a
.您将
a
强制转换为子类,然后您可以从 a 上a
子类访问方法。 If it´s not even possible to cast an object to a subclass, you get an error at compile time.如果甚至无法将 object 强制转换为子类,则在编译时会出现错误。
Change your Main
class to the following and it should do what you want:将您的
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
}
}
}
A few examples of when casting work and don't work at compile time and runtime:在编译时和运行时强制转换工作和不工作的几个例子:
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)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.