Java subclass 从离散 class 和接口?
Java subclassing from discrete class and interface?
下图描述了 MyClass
和 MyOtherClass
的层次结构。使用 Java 是否可以定义一个可以保存 MyClass
和 MyOtherClass
值的变量,即将值限制为子 class 的实例的变量定义JComponent
的 ]es 和 MyInterface
的实现,以便 JComponent
和 MyInterface
的功能同时可用?
我意识到这样做的正常方法是创建一个扩展 JComponent
并实现 MyInterface
的中间抽象 class,所以我想知道如果没有这种行为是否可能这样做。
奇怪的 class 层次结构背后的原因是我最初创建 MyAbstractClass
用作通用视觉类型,现在想为其添加一些功能,即 MyInterface
,用于其他地方。然而,我还需要制作一些新的 classes,它们具有与 MyInterface
相同的附加功能,但不是 MyAbstract class 的实例。如果我不必创建一个重复的 MyAbstractClass
来扩展一些其他中间 class 扩展 Jcomponent
和 MyInterface
.
就好了
o JComponent
|
|\
| \
| \
| o MyInterface
| |
| |\
| | |
|\ | o MyClass
| | |
| o | MyAbstractClass
| | |
| | |
| | /
| |/
| |
| o MyOtherClass
只要变量对于任何给定实例保持相同类型,您就可以为变量使用上限通用类型,并通过构造函数或修改器方法注入对象。
以您的层次结构为例,Foo
下方有一个 T
类型的变量 bar
,它必然是 JComponent
和 [=22] 的子类型=] 在这种情况下。然后你可以构造一个 Foo
的实例来定义具体类型。实际上,您最好定义一个 JComponent
的抽象子类来提供 MyInterface
方法。这样你就不会被通用类型所束缚。
富
public class Foo<T extends JComponent & MyInterface> {
private T bar;
public Foo(T bar) {
this.bar = bar;
}
public void fooAction() {
bar.interfaceMethod(); // MyInterface method
System.out.println(bar.getWidth()); // JComponent method
}
}
用法
public class Main {
public static void main(String[] args) {
Foo<MyClass> a = new Foo<>(new MyClass());
Foo<MyOtherClass> b = new Foo<>(new MyOtherClass());
a.fooAction();
b.fooAction();
}
}
输出
MyClass
0
MyOtherClass
0
同样的原则也适用于静态方法,例如:
public class Main {
public static void main(String[] args) {
staticAction(new MyClass());
staticAction(new MyOtherClass());
}
public static <T extends JComponent & MyInterface> void staticAction(T bar) {
bar.interfaceMethod();
System.out.println(bar.getWidth());
}
}
为了完整起见,本例中使用的类:
MyAbstractClass
public abstract class MyAbstractClass extends JComponent { }
我的界面
public interface MyInterface {
void interfaceMethod();
}
MyClass
public class MyClass extends JComponent implements MyInterface {
@Override
public void interfaceMethod() {
System.out.println("MyClass");
}
}
MyOtherClass
public class MyOtherClass extends MyAbstractClass implements MyInterface {
@Override
public void interfaceMethod() {
System.out.println("MyOtherClass");
}
}
下图描述了 MyClass
和 MyOtherClass
的层次结构。使用 Java 是否可以定义一个可以保存 MyClass
和 MyOtherClass
值的变量,即将值限制为子 class 的实例的变量定义JComponent
的 ]es 和 MyInterface
的实现,以便 JComponent
和 MyInterface
的功能同时可用?
我意识到这样做的正常方法是创建一个扩展 JComponent
并实现 MyInterface
的中间抽象 class,所以我想知道如果没有这种行为是否可能这样做。
奇怪的 class 层次结构背后的原因是我最初创建 MyAbstractClass
用作通用视觉类型,现在想为其添加一些功能,即 MyInterface
,用于其他地方。然而,我还需要制作一些新的 classes,它们具有与 MyInterface
相同的附加功能,但不是 MyAbstract class 的实例。如果我不必创建一个重复的 MyAbstractClass
来扩展一些其他中间 class 扩展 Jcomponent
和 MyInterface
.
o JComponent
|
|\
| \
| \
| o MyInterface
| |
| |\
| | |
|\ | o MyClass
| | |
| o | MyAbstractClass
| | |
| | |
| | /
| |/
| |
| o MyOtherClass
只要变量对于任何给定实例保持相同类型,您就可以为变量使用上限通用类型,并通过构造函数或修改器方法注入对象。
以您的层次结构为例,Foo
下方有一个 T
类型的变量 bar
,它必然是 JComponent
和 [=22] 的子类型=] 在这种情况下。然后你可以构造一个 Foo
的实例来定义具体类型。实际上,您最好定义一个 JComponent
的抽象子类来提供 MyInterface
方法。这样你就不会被通用类型所束缚。
富
public class Foo<T extends JComponent & MyInterface> {
private T bar;
public Foo(T bar) {
this.bar = bar;
}
public void fooAction() {
bar.interfaceMethod(); // MyInterface method
System.out.println(bar.getWidth()); // JComponent method
}
}
用法
public class Main {
public static void main(String[] args) {
Foo<MyClass> a = new Foo<>(new MyClass());
Foo<MyOtherClass> b = new Foo<>(new MyOtherClass());
a.fooAction();
b.fooAction();
}
}
输出
MyClass
0
MyOtherClass
0
同样的原则也适用于静态方法,例如:
public class Main {
public static void main(String[] args) {
staticAction(new MyClass());
staticAction(new MyOtherClass());
}
public static <T extends JComponent & MyInterface> void staticAction(T bar) {
bar.interfaceMethod();
System.out.println(bar.getWidth());
}
}
为了完整起见,本例中使用的类:
MyAbstractClass
public abstract class MyAbstractClass extends JComponent { }
我的界面
public interface MyInterface {
void interfaceMethod();
}
MyClass
public class MyClass extends JComponent implements MyInterface {
@Override
public void interfaceMethod() {
System.out.println("MyClass");
}
}
MyOtherClass
public class MyOtherClass extends MyAbstractClass implements MyInterface {
@Override
public void interfaceMethod() {
System.out.println("MyOtherClass");
}
}