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



好的,所以在我的程序我有一些标签(这是在一个数组和东西)无论如何,我想添加我自己的属性到内置的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)是undefined"

为什么不直接继承超类的东西?我尝试将构造函数添加到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, i再次得到undefined

方法setImage(Image)是未定义的类型labelMod

编辑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其余

这里有几个问题。

首先,你混淆了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吗?推荐的SWT工作流是构建一个包装或包含LabelComposite,并在包装类中执行自定义工作。实际上,您需要重写一些内置检查,以便能够创建SWT小部件的子类。您必须重写以下方法:

protected void checkSubclass()
{
    /* Allow us to subclass this widget. */
}

第三,我不确定Label上的createContents方法是什么。由于SWT是本机窗口系统的包装器,因此不同的Label在不同的平台上可能具有不同的私有实现。例如,在Mac OS上,Label或它的任何祖先都没有createContents方法,这将表明这是一个无法重写的私有方法。你需要找到一个不同的方法来重写以改变你所看到的行为。

为此,我要再问一遍——您确定真的需要重写 Label,而不是简单地使用自己的Composite在它周围创建一个包装器吗?我编写SWT应用程序已经有好几年了,我需要只扩展一个SWT小部件一次,而且只是为了一个微不足道的更改,而我已经创建了无数包含或包装其他小部件的Composite

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

对于数组,可以将子类的实例赋值给超类变量,但不能反过来。这表明类型为Label[]的数组可以正常工作;它既可以保存普通的Label实例,也可以保存labelMod实例。

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

编辑:

java.awt。标签有3种构造函数

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

和org.eclipse.swt.widgets.Label有1种构造函数

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混在一起了。这是真的吗?

我是一个swing家伙,所以我没有使用swt,但看起来你不应该覆盖标签类,有检查阻止你。

还要检查你的构造函数,你只能传递给父类构造函数可以接受的变量。所以检查javadock。不能将超类强制转换为它的子类,除非它是作为该子类构造的。

我认为可能发生的事情是,当您最初创建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;
}
}

没有与构造函数签名匹配的构造函数(看这里),所以当您调用

super(shlTictactoe,none)

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

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

例如,如果父类有一个属性"label",那么在你的子类中你将创建一个方法:

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

大多数ide都有方法可以轻松地生成委托方法,而无需全部手工编码。例如,在Netbeans中,"alt+insert"将弹出一个代码生成选项菜单,您可以在其中选择委托,然后选择要为其创建委托方法的包含类或超类。

最新更新