在java中扩展一个类,但它不会从超类继承属性

时间:2011-10-12 12:46:03

标签: java swt extend superclass

好吧,在我的程序上我有一些标签(在数组和东西中)无论如何我想将自己的属性添加到内置的Label类,无论如何所以我尝试扩展它

public class LabelMod extends Label

但每当我尝试更改它所以它创建我的新类型标签而不是createContents()方法中的默认值时,它似乎不会继承原始标签属性并且我得到一堆错误

public void createContents()
{

    shlTictactoe = new Shell();
    shlTictactoe.setSize(450, 300);
    shlTictactoe.setText("TicTacToe");

然后有9个以下实例(g1x1,g1x2,g1x3,g2x1等)

LabelMod g1x1 = new LabelMod(shlTictactoe, SWT.NONE);
    g1x1.addMouseListener(new MouseAdapter()
    {
        @Override
        public void mouseDown(MouseEvent e)
        {
            changeSt(0);
        }
    });
    g1x1.setImage(SWTResourceManager.getImage(MainForm.class,
            "/res/blank.png"));
    g1x1.setBounds(10, 10, 64, 64);

然后将它们放在一个数组中

createArray(g1x1, g1x2, g1x3, g2x1, g2x2, g2x3, g3x1, g3x2, g3x3);

我正在使用SWT创建一个gui,并在主窗体上有一些标签。为什么我不能创建新类型的标签(我添加了额外的属性)?

对于这个特定的例子,它说“构造函数LabelMod(Shell,int)是未定义的”

为什么它只是继承了超类中的东西?我尝试将构造函数添加到labelMod类,但它也给出了一个未定义的错误。然而,错误在主类中得到修复。

public LabelMod(Shell shlTictactoe, int none)   
    {
        super(shlTictactoe,none);
        // TODO Auto-generated constructor stub
    }

我的另一个想法是将一些标签分配给LabelMods,但因为它们与它抱怨的类型不同。 她的意思是:

Label g1x1 = new Label(shlTictactoe, SWT.NONE);     
g1x1.setImage(SWTResourceManager.getImage(MainForm.class,
            "/res/blank.png"));
g1x1.setBounds(10, 10, 64, 64);

然后我有一个数组

public LabelMod[] labelArray = new LabelMod[9];

然后我将其分配给标签

labelArray[0] = g1x1;
显然,因为它们是不同的类型,它可能起作用,但也许它可以转换它或什么?

请注意: 如果我只使用正常的Label而不是我的修改版本,一切都有效,所以我知道这不是问题。

修改

这是完整的课程,如果它有帮助

public class LabelMod extends Label {


public LabelMod() throws HeadlessException
{
    super();
    // TODO Auto-generated constructor stub
}

public LabelMod(String text, int alignment) throws HeadlessException
{
    super(text, alignment);
    // TODO Auto-generated constructor stub
}

public LabelMod(String text) throws HeadlessException
{
    super(text);
    // TODO Auto-generated constructor stub
}

public LabelMod(Shell shlTictactoe, int none)   
{
    super(shlTictactoe,none);
    // TODO Auto-generated constructor stub
}

public boolean isActivated;

public boolean isActivated()
{
    return isActivated;
}

public void setActivated(boolean isActivated)
{
    this.isActivated = isActivated;
}

}

我也发现如果我将鼠标悬停在原始(工作)Label(shlTictactoe, SWT.NONE);上格式为

Label(Composite parent, int style)

编辑2: addMouseListener表示

也有错误
  

Component类型中的方法addMouseListener(MouseListener)   不适用于参数(new MouseAdapter(){})

setImage我再次未定义

  

对于类型labelMod

,方法setImage(Image)未定义

编辑3 一个细节我认为不重要,但可能对这个问题至关重要......这些是LabelMod类的导入 - 请记住它的SWT项目

import java.awt.HeadlessException;
import java.awt.Label;

import org.eclipse.swt.widgets.Shell;

编辑4

好吧所以我添加了相应的导入(swt这次 - 确定)所以现在我的导入是:

import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

但是现在我得到一个运行时错误,如果我进入设计器视图,所有标签都没有正确显示这里是我在控制台中得到的:

org.eclipse.swt.SWTException: Subclassing not allowed
at org.eclipse.swt.SWT.error(SWT.java:4282)
at org.eclipse.swt.SWT.error(SWT.java:4197)
at org.eclipse.swt.SWT.error(SWT.java:4168)
at org.eclipse.swt.widgets.Widget.error(Widget.java:468)
at org.eclipse.swt.widgets.Widget.checkSubclass(Widget.java:313)
at org.eclipse.swt.widgets.Widget.<init>(Widget.java:148)
at org.eclipse.swt.widgets.Control.<init>(Control.java:110)
at org.eclipse.swt.widgets.Label.<init>(Label.java:101)
at Main.LabelMod.<init>(LabelMod.java:16)
at Main.MainForm.createContents(MainForm.java:99)
at Main.MainForm.open(MainForm.java:39)
at Main.MainForm.main(MainForm.java:26)

并在错误日志中记录:

Designer [1.1.0.r37x201109091012.201110120013]: new Label(shell, SWT.NONE)
其余的

http://pastebin.com/ru1QCU0A

7 个答案:

答案 0 :(得分:1)

你在这里遇到了一些问题。

首先,您要混淆org.eclipse.swt.widgets.Labeljava.awt.Label。你(我认为)试图覆盖org.eclipse.swt.widgets.Label,这意味着你需要有一个合适的构造函数。这意味着:

public LabelMod(Shell parent, int style)
{
    super(parent, style);
}

您不需要任何带有String参数的构造函数。这适用于java.awt.Label,而不适用于SWT。

其次,您确定要覆盖Label吗? recommended SWT workflow是构建包含或包含Composite的{​​{1}}并在包装类中进行自定义工作。实际上,您需要覆盖甚至能够子类化SWT窗口小部件的内置检查。您必须覆盖以下方法:

Label

第三,我不确定protected void checkSubclass() { /* Allow us to subclass this widget. */ } 上的createContents方法是什么。由于SWT是本机窗口系统的包装器,因此不同的Label可能在不同平台上具有不同的私有实现。例如,在Mac OS上,Label或其任何祖先都没有createContents方法,这表明这是一个无法覆盖的私有方法。您需要找到一种不同的方法来覆盖以改变您所看到的行为。

为此,我会再次提问 - 你确定你确实需要覆盖 Label而不是简单地使用你自己的Label创建一个包装器吗? ?我已经编写SWT应用程序好几年了,我已经需要扩展一个SWT小部件一次,只是为了一个微不足道的改变,而我已经创建了无数Composite s包含或包装其他小部件。

答案 1 :(得分:0)

构造函数不是继承的,因此您需要为子类定义自己的构造函数。我想如果你仔细再试一次,你会发现你所展示的代码是有效的(假设你在super行的末尾添加了缺少的分号。

然后关于你的数组,你可以将一个子类的实例分配给一个超类变量,但不是相反。这表明类型Label[]的数组可以正常工作;它可以包含常规的Label以及labelMod个实例。

我应该指出Java有一套非常强大的命名约定;类总是以大写字母命名。如果你违反了这一点,那么对于有经验的人来说,这会让你的代码更难阅读。

答案 2 :(得分:0)

修改

java.awt.Label有3种类型的构造函数

Label()
Label(String)
Label(String, int)

和org.eclipse.swt.widgets.Label有一种类型的构造函数

Label(Composite, int)

你如何能够同时调用它

public labelMod(Shell shlTictactoe, int none)   
    {
        super(shlTictactoe,none);
        // TODO Auto-generated constructor stub
    }

public LabelMod(String text, int alignment) throws HeadlessException
{
    super(text, alignment);
    // TODO Auto-generated constructor stub
}

我认为你正在混合使用SWT和AWT。这可能是真的吗?

答案 3 :(得分:0)

我是摇摆人,所以我没有使用swt,但看起来你不应该克服Label类,并且有检查阻止你。

同样检查你的构造函数,你只能将变量传递给超类构造函数可以采用的超类。所以检查javadock。除非将超类构造为该子类,否则不能将超类强制转换为它的子类。

答案 4 :(得分:0)

我认为可能发生的事情是,当您最初创建LabelMod时,您的导入错误,可能是java.awt.Label而不是swt。您使用的工具,Eclipse我假设,根据所选的超类(即Label而不是org.eclipse.swt.widgets.Label)为您创建了所有构造函数。

所以,回答这个问题,你应该没有问题扩展org.eclipse.swt.widgets.Label并添加你自己的属性和方法或覆盖现有的方法,但是,特别是如果使用创建大量“存根”的工具代码,你需要确保你拥有正确的超类。也许这就是你要找的东西:

import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

public class LabelMod extends Label {

public LabelMod(Composite parent, int style) {
    super(parent, style);
    // TODO Auto-generated constructor stub
}

public boolean isActivated;

public boolean isActivated() {
    return isActivated;
}

public void setActivated(boolean isActivated) {
    this.isActivated = isActivated;
}

}

答案 5 :(得分:-1)

子类确实继承,但是超类访问器方法本身不可访问。能够从超类获取/设置值的简单方法是在子类中设置委托方法。

例如,如果超类具有属性“label”,则在子类中创建一个方法:

public String getLabel(){
    return super.getLabel();
}

public void setLabel(String label){
    super.setLabel(label);
}

大多数IDE都可以轻松生成委托方法,而无需手动编码。例如,在Netbeans中,“alt + insert”将显示一个代码生成选项菜单,您可以在其中选择委托,然后选择包含的类或超类来为其创建委托方法。

答案 6 :(得分:-1)

没有构造函数符合构造函数的签名(看here),所以当你调用时

super(shlTictactoe,none)

它无法在标签上找到合适的构造函数。你需要传入一个String和一个int。