简体   繁体   English

如何在超类中使用子类方法?

[英]How to use subclass methods in superclass?

I have a superclass called Parameter. 我有一个名为Parameter的超类。 There are many different types of parameters and they have different methods of course. 参数有很多不同的类型,它们当然有不同的方法。 The problem is I initialize the Parameter as one of the subs but still it doesn't allow me to use the subclass events! 问题是我将Parameter初始化为子项之一,但仍然不允许我使用子类事件!

 package com.lbg.c2;

public class Parameter {

private  String  type;

public static final Parameter NumberParam = new NumberParam();
public static final Parameter StringParam = new StringParam();
public static final Parameter AnyTypeParam = new AnyTypeParam();
public static final Parameter AnimationParam = new AnimationParam();
public static final Parameter AudioParam = new AudioParam();
public static final Parameter CmpParam = new CmpParam();
public static final Parameter ComboOptionParam = new ComboOptionParam();
public static final Parameter ComboParam = new ComboParam();
public static final Parameter KeybParam = new KeybParam();
public static final Parameter LayerParam = new LayerParam();
public static final Parameter LayoutParam = new LayoutParam();
public static final Parameter ObjectParam = new ObjectParam();

public Parameter () {

}

public Parameter (String t) {
    type = t;
}

public String getType() {
    return type;
}

public static Parameter init (String t) {
    if (t.equals("number")) {
        return NumberParam;
    }
    else if (t.equals("string")) {
        return StringParam;
    }
    else if (t.equals("any type")) {
        return AnyTypeParam;
    }
    else if (t.equals("animation")) {
        return AnimationParam;
    }
    else if (t.equals("audio")) {
        return AudioParam;
    }
    else if (t.equals("comparision")) {
        return CmpParam;
    }
    else if (t.equals("combo option")) {
        return ComboOptionParam;
    }
    else if (t.equals("combo")) {
        return ComboParam;
    }
    else if (t.equals("keyboard")) {
        return KeybParam;
    }
    else if (t.equals("layer")) {
        return LayerParam;
    }
    else if (t.equals("layout")) {
        return LayoutParam;
    }
    else if (t.equals("object")) {
        return ObjectParam;
    }
    else {
        return new Parameter();
    }
}

} }

This method is found statically in Parameter class so when you it can init it from the string passed. 该方法在Parameter类中静态找到,因此当您可以从传递的字符串中对其进行初始化时。

        add.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            String types [] = {"number","string","any type","comparision","combo option",
            "combo","object","layer","layout","keyboard","animation","audio"};
            JComboBox<String> box = new JComboBox<String>(types);
            JLabel text = new JLabel ("Select the parameter type:\n");
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            panel.add(text, BorderLayout.NORTH);
            panel.add(box, BorderLayout.SOUTH);

            JOptionPane.showMessageDialog(frame, panel, "New Parameter", JOptionPane.QUESTION_MESSAGE);

            Parameter p = Parameter.init((String) box.getSelectedItem());

            if (p instanceof NumberParam || p instanceof StringParam || p instanceof AnyTypeParam) {
                String label = JOptionPane.showInputDialog(frame,"Parameter Label?","New Parameter",JOptionPane.QUESTION_MESSAGE);
                p.setLabel(label); // it says it needs casting!!
            }
        }

    });

Here now the Parameter static method must return aa subclass of the Parameter class but still it doesn't allow me. 现在,这里的Parameter静态方法必须返回Parameter类的一个子类,但仍然不允许我这样做。 But now it is a subclass then why it doesn't allow me to use its methods? 但是现在它是一个子类,那为什么为什么不允许我使用它的方法呢?

It's like saying You are a device and then I subclass you to a Phone and you can't call others because you are still known as a device 这就像说您是设备,然后我将您归类为“电话”,而您无法呼叫其他人,因为您仍然被称为设备

A Parent class can never knows who are those Child classes which are inherited from it. Parent类永远不会知道谁是从其继承的Child类。 If you have define a method in the Child class it can only be accessed by/called upon Child class instance . 如果您在Child类中定义了一个方法,则只能由Child类instance对其进行调用。 While the reverse in not true, if a method is defined in Parent Class all the Child class instances can access it/call it. 反之则不然,如果在Parent Class定义了一个方法,则所有Child class实例都可以访问/调用它。

Eg:- 例如:-

Object o = new String("Hi"); //will work because Object is parent class of String 
o.trim(); // can't call/will give compilation error because parent Object does not know child String's trim()
if(o.getClass().equals(String.class) ){ // check actual runtime class of o
            String ss = (String) o; //typecasting
            System.out.println(ss.trim()); // will work on String object
        }

You can't use the subclass methods because in 您不能使用子类方法,因为在

Parameter p = Parameter.init((String) box.getSelectedItem());

you are declaring p as type Parameter. 您将p声明为Parameter类型。 You will only ever be able to call the methods declared in Parameter. 您将只能调用在Parameter中声明的方法。

You could explicitly cast the created subclass after the fact like so: 您可以在发生以下情况之后显式转换所创建的子类:

  Parameter p = Parameter.init((String) box.getSelectedItem());
  NumberParameter np = (NumberParameter)p;

But I think you are thinking about java inheritance wrong. 但是我认为您在考虑Java继承错误。 The point of the factory pattern is to provide different concrete implementations of an interface like Parameter. 工厂模式的重点是提供诸如Parameter之类的接口的不同具体实现。 This is useful to the extent that the setLabel() method on the different subclasses does something different. 就不同子类上的setLabel()方法所做的不同而言,这很有用。

You're only ever declaring the result as a Parameter , and a parent class has no knowledge of what its children have declared (or that would break encapsulation). 您只将结果声明为Parameter ,而父类不知道其子代声明了什么(否则将破坏封装)。

If you want to be sure that you always get the right type, then consider passing in the Class that you want to use in that scenario. 如果要确保始终获得正确的类型,请考虑传入要在该方案中使用的Class

A sample signature would look like this: 示例签名如下所示:

public static <T extends Parameter> T init(Class<T> clazz) throws InstantiationException, IllegalAccessException {
    return clazz.newInstance();
}

You'll have to do something if either of those methods are thrown, though. 但是,如果抛出其中一种方法,则必须执行某些操作。

A sample call would look something like this: 调用示例如下所示:

// I want a NumberParameter
NumberParameter p = Parameter.init(NumberParameter.class);

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

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