简体   繁体   English

超类类型对象的子类构造方法?

[英]Constructor method of subclass for a superclass type object?

I have seen constructer method of subclass being used for a variable with superclass type. 我已经看到子类的构造方法用于具有超类类型的变量。 For example: 例如:

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

Is formatter a DateFormat type object or a SimpleDateFormat type? formatterDateFormat类型对象还是SimpleDateFormat类型? Since the class SimpleDateFormat inherit from DateFormat , it probably has more methods than its superclass. 由于类SimpleDateFormat继承自DateFormat ,因此它可能比其超类具有更多的方法。 Can the instance formatter call these functions only exist in SimpleDateFormat but not DateFormat ? 实例formatter能否仅在SimpleDateFormat存在这些函数,而在DateFormat不存在? Are DateFormat and SimpleDateFormat interchangeable in this case? 在这种情况下, DateFormatSimpleDateFormat是否可以互换? such as: 如:

SimpleDateFormat formatter = new DateFormat ("yyyy-MM-dd");

The runtime type of formatter is determined by the constructor used to instantiate it, and its compile-time type is the one you used in the declaration. formatter的运行时类型由用于实例化它的构造函数确定,其编译时类型是您在声明中使用的类型。 You cannot call a method on formatter that would exist on its actual runtime type and not on its declaration type, unless you use a cast to resolve the method call. 您不能在格式化程序上调用实际存在于其运行时类型而不是其声明类型上的方法,除非您使用强制类型转换来解决该方法调用。

By the way, you could have answered your own questions by simple experiments : 顺便说一句,您可以通过简单的实验回答自己的问题:

public class SuperClass {
    public void test() {
        System.out.println("Test");
    }

    public static class SubClass extends SuperClass {
        public void testSub() {
            System.out.println("Test sub");
        }

        @Override
        public void test() {
            System.out.println("Override test");
        }
    }

    public static void main(String[] args) {
        SuperClass sc = new SuperClass();
        sc.test();                      // prints Test
        sc = new SubClass();
        sc.test();                      // prints Override test
        sc.testSub();                   // does not compile
        ((SubClass) sc).testSub();      // prints Test sub
    }
}

The type of a Java instance is determined by the constructor used for creating it, and cannot be changed. Java实例的类型由用于创建它的构造函数确定,并且不能更改。

The methods that may be invoked on an instance, depend on the type of the variable used to reference it. 可以在实例上调用的方法取决于用于引用实例的变量的类型。 Therefore, you may invoke different sets of methods over the same instance, depending on the type of the variable you use to reference it. 因此,您可以在同一实例上调用不同的方法集,具体取决于用于引用它的变量的类型。

The type of the variable used to reference an instance ONLY may be: 仅用于引用实例的变量的类型可以是:

  • The same type of the referenced instance 相同类型的引用实例
  • A superclass of the type of the referenced instance 引用实例类型的超类
  • An interface implemented by the type of the reference instance. 由参考实例的类型实现的接口。

The higher in the class hierarchy that is the variable, the more general (and therefore, reusable) is the code that uses it. 在类层次结构中,变量越高,使用该变量的代码就越通用(因此可重用)。 As a rule of design, you should use Interfaces as variable (and specially parameter) types. 作为设计规则,应将接口用作变量(特别是参数)类型。

Suggest you to read this: http://en.wikipedia.org/wiki/Liskov_substitution_principle 建议您阅读以下内容: http : //en.wikipedia.org/wiki/Liskov_substitution_principle

formatter is of both types, DateFormat and SimpleDateFormat . formatter有两种类型, DateFormatSimpleDateFormat As soon as you call the constructor for SimpleDateFormat , it also calls the constructor for DateFormat - but it is only one Object. 调用SimpleDateFormat的构造函数后,它也会调用DateFormat的构造函数-但它只是一个对象。

To access methods from SimpleDateFormat , you can cast it: 要从SimpleDateFormat访问方法,可以将其SimpleDateFormat为:

SimpleDateFormat sdf = (SimpleDateFormat) formatter;

This only works as long as formatter is of type SimpleDateFormat or any subclass of it. 仅当formatter的类型为SimpleDateFormat或其任何子类时,此方法才有效。 The following line will produce an compile error: 以下行将产生编译错误:

SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateTimeInstance();

By the way, I would just declare formatter as a SimpleDateFormat from the beginning. 顺便说一句,我从一开始就将formatter声明为SimpleDateFormat You have no benefit from declaring it as a DateFormat and than cast it - this is a waste of your CPU. 将其声明为DateFormat而不是DateFormat将不会带来任何好处-这浪费您的CPU。

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

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