简体   繁体   English

Java中的多态性-我可以将对象设置为特定类型吗?

[英]Polymorphism in Java - can I set an object to a specific type?

I am a programmer who is getting to grasps with polymorphism after a long break and I was wondering if the following is possible. 我是一个程序员,经过长时间的休息后就开始掌握多态性,我想知道以下可能性是否可行。 Say I had a super class in which there were some instance variables A, B and C. In all subclasses A and B are strings and behave as such in all subclasses however in all of the subclasses, the type of C may depend on the state of the subclass. 假设我有一个超类,其中有一些实例变量A,B和C。在所有子类中,A和B都是字符串,并且在所有子类中均具有相同的行为,但是在所有子类中,C的类型可能取决于状态子类的。 I was wondering if it is possible to set C as type 'Object' in the superclass and then specify its type in each subclass using wrapper classes. 我想知道是否可以在超类中将C设置为“对象”类型,然后使用包装器类在每个子类中指定其类型。 eg 例如

public class SuperClass {
    String A;
    String B;
    Object C;

    public SuperClass(){}
    }
}
public class SubClassA extends SuperClass {

    public SubClassA () {
        C = new String(); //notice this type is different from its type in the next class
    }

}

public class SubClassB extends SuperClass {

    public SubClassB () {
        C = new Integer();
    }
}

your thoughts would be appreciated :) Thanks 您的想法将不胜感激:)谢谢

No. "Set an object to a specific type" does not mean anything. 否。“将对象设置为特定类型”没有任何意义。 In fact, "Set an object." 实际上是“设置对象”。 does not mean anything. 没什么意思

A, B, and C in your example are not objects, they are variables. 您的示例中的A,B和C不是对象,而是变量。 There are three kinds of variable in Java; Java中有三种变量: primitives (eg, int, boolean, double), array reference variables, and object reference variables. 原语(例如int,boolean,double),数组引用变量和对象引用变量。 A, B, and C are object reference variables. A,B和C是对象引用变量。 That means, A, B, and C each hold the identity of some object. 也就是说,A,B和C各自持有某个对象的身份

Initially, they all hold null which is a special object reference that means "no object." 最初,它们全都为null ,这是特殊的对象引用,表示“无对象”。

Your subclass constructors each create a new object, and store its identity in C. 您的子类构造函数均会创建一个新对象,并将其标识存储在C中。

Objects have types which can be known at run-time, and variables have types which are only known at compile time. 对象的类型在运行时是已知的,变量的类型仅在编译时是已知的。 The compiler will reject your code if it can prove that you assign the identity of some object to an object reference variable with an incompatible type. 如果编译器可以证明您将某个对象的身份分配给类型不兼容的对象引用变量,则编译器将拒绝您的代码。

The type of variable C, Object, is compatible with any object. 变量C的类型Object可以与任何对象兼容。 You can assign a String reference to it, or you can assign an Integer reference to it, or you can assign a ForkJoinPool.ForkJoinWorkerThreadFactory reference to it. 您可以为其分配String引用,也可以为其分配Integer引用,也可以为其分配ForkJoinPool.ForkJoinWorkerThreadFactory引用。 The downside, is that the compiler will only let you perform operations through C that can be performed on every type of object. 缺点是,编译器将只允许您通过C执行可以在每种类型的对象上执行的操作。 The compiler won't allow you to call C.toUpperCase()---not even if it holds a reference to an actual String object.---because you have explicitly declared that C may hold references to things that are not Strings. 编译器不会让你打电话C.toUpperCase()---甚至没有,如果它拥有一个实际String对象的引用.---因为你已经明确宣布,C 可以坚持的东西不是 String引用。


I would not write the code that you wrote, but it's hard to say what I would write instead, because your example doesn't actually do anything. 我不会写您编写的代码,但是很难说要写什么,因为您的示例实际上并没有执行任何操作。 You'll get better answers in this forum if you ask questions about how to solve actual problems. 如果您提出有关如何解决实际问题的问题,您将在此论坛中获得更好的答案。

Understand, first and foremost, the difference between an object and a reference . 首先,最重要的是要了解对象参考之间的区别。 An object is something that you create with new and it has a specific type (class) that is fixed from the moment it's created. 对象是您使用new创建的对象 ,并且具有特定的类型(类),该类型从创建之日起即已确定。 A reference is a "pointer" to an object. 引用是对象的“指针”。

A single reference can point to different types of objects at different times, so long as the declared type of the reference is the class of the object or its superclass . 只要引用的声明类型是对象的类或其超类,则单个引用可以在不同的时间指向不同类型的对象。 Object is the superclass of all objects (including arrays, but not "scalars" like int , char , float , etc) and hence a reference declared with type Object can point to any object. Object是所有对象(包括数组,但不是诸如intcharfloat等的“标量”)的超类,因此使用Object类型声明的引用可以指向任何对象。

Of course, if you have a reference declared as Object then even if you (supposedly) know what's in it, the compiler and JVM haven't a clue. 当然,如果您有一个引用声明为Object则即使您(应该)知道其中的内容,编译器和JVM也没有任何提示。 So you need to "cast" the reference to the appropriate type before you can use it. 因此,您需要先将引用“投射”到适当的类型,然后才能使用它。 Eg, knowing that you previously stored a pointer to a String object into C , you might do: 例如,知道您之前将指向String对象的指针存储到C ,则可以这样做:

String castFromC = (String)C;
Char charFromC = castFromC.charAt(5);

If it turns out that C is not a String but is instead an Integer, then the (String) "cast" operation will fail at runtime with a ClassCastException. 如果事实证明C不是一个字符串而是一个整数,则(String) “ cast”操作将在运行时失败,并显示ClassCastException。

From my understanding of your concern, your posted code looks OK to me. 根据我对您所关注问题的了解,您发布的代码对我来说还可以。 However, it will force you to cast C to a specific type for it to be "operable" since you just declared the object reference C as just a "reference pointing to an Object type of Java object". 但是,由于您只是将对象引用C声明为“指向Java对象的Object类型的引用”,因此它将强制将C强制转换为特定类型以使其“可操作”。

To avoid the ugly typecasting, you can generify your superclass like this 为了避免丑陋的类型转换,您可以像这样生成您的超类

class SuperClass<T> {
    String A;
    String B;
    T C;

    public SuperClass(){}
}

And in your subclasses, you can use it like this 在子类中,您可以像这样使用它

class SubClassA extends SuperClass<String> {

    public SubClassA () {
        C = new String();
    }
}

class SubClassB extends SuperClass<Integer> {

    public SubClassB () {
        C = new Integer(0);
    }
}

Also, it is a convention that your instance variables should have a meaningful name starting with lowercase, declared private, and exposed to other classes with public getters and setters. 同样,根据惯例,您的实例变量应以小写字母开头,声明为私有并在其他具有公共getter和setter的类中公开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM