Java动态继承
让ClassA表示一个抽象类 我想知道是否可以在Java中执行类似的操作:Java动态继承,java,class,inheritance,abstract-class,Java,Class,Inheritance,Abstract Class,让ClassA表示一个抽象类 我想知道是否可以在Java中执行类似的操作: public static abstract class ClassA { abstract void foo(); } private ClassB extends ClassA a = new ClassA() { // define abstract methods here foo() { System.out.println("in anon!"); } // defi
public static abstract class ClassA {
abstract void foo();
}
private ClassB extends ClassA a = new ClassA() {
// define abstract methods here
foo() { System.out.println("in anon!"); }
// define OTHER variables here
public int varB = 10;
}
// later... varB is not defined in ClassA, but it is in a.
// how can I access varB from a?
System.out.println(a.varB);
我想特别提醒一下:注意我是如何打印varB的。假设varB不是在ClassA中定义的,只是在匿名内部类中定义的
我有很多抽象类,当我创建它们时,我会动态地定义它们的抽象方法。但是,我也希望将这些类视为它们自己的类型,因为有时我需要访问该类中特定于该对象版本的变量
是否有一种类似于我上面所展示的方法,或者我需要创建一个每次都从“ClassA”扩展而来的“ClassB”
有什么解决办法吗
谢谢试试看。样本如下:
abstract class ClassA {
abstract void eat();
}
class TestAnonymousInner{
public static void main(String args[]){
ClassA p=new ClassA (){
void eat(){System.out.println("nice fruits");}
};
p.eat();
}
}
编辑:
就访问变量varA
而言,您需要在抽象类中声明该变量,因为ClassA
需要关于该变量的信息。在这里,我们可以将p
引用的对象视为父类引用的ClassA的子类,因此父类无权访问子类(在本例中为匿名类)中引入的方法和变量。请尝试。示例如下:
abstract class ClassA {
abstract void eat();
}
class TestAnonymousInner{
public static void main(String args[]){
ClassA p=new ClassA (){
void eat(){System.out.println("nice fruits");}
};
p.eat();
}
}
编辑:
就访问变量
varA
而言,您需要在抽象类中声明该变量,因为ClassA
需要关于该变量的信息。在这里,我们可以将p
引用的对象视为ClassA的子类,该子类由父类引用,因此父类无权访问子类(在本例中为匿名类)中引入的方法和变量。匿名类是否不适合您的用例
public static void main(String[] args) {
// Make an anonymous instance of A
final A first = new A() {
private final int i = 10;
void foo() {
System.out.println(i);
}
};
// Make another anonymous instance of A
final A second = new A() {
private final String message = "Listen!";
void foo() {
System.out.println("Hey!");
System.out.println(message);
}
};
// They do their own unique things
first.foo();
second.foo();
// Both have A as a super-type
System.out.println(first instanceof A);
System.out.println(second instanceof A);
// But first and second are *not* A and therefore not the same class!
final boolean isSameClass = first.getClass().equals(second.getClass());
System.out.println(isSameClass);
}
static abstract class A {
abstract void foo();
}
这里的想法是,当您创建一个新的匿名类时,您实际上是在为单个实例子键入您使用的类。这就是为什么双括号初始值设定项是个坏主意的部分原因
编辑:访问仅属于匿名类的变量。但是,如果您对反射没有意见,类似的方法可能会奏效:
try {
final Field i = first.getClass().getDeclaredField("i");
i.setAccessible(true);
System.out.println(i.getInt(first));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
这相当混乱,我不一定推荐它,但它确实完成了您在这里要做的事情。匿名类是否不适合您的用例
public static void main(String[] args) {
// Make an anonymous instance of A
final A first = new A() {
private final int i = 10;
void foo() {
System.out.println(i);
}
};
// Make another anonymous instance of A
final A second = new A() {
private final String message = "Listen!";
void foo() {
System.out.println("Hey!");
System.out.println(message);
}
};
// They do their own unique things
first.foo();
second.foo();
// Both have A as a super-type
System.out.println(first instanceof A);
System.out.println(second instanceof A);
// But first and second are *not* A and therefore not the same class!
final boolean isSameClass = first.getClass().equals(second.getClass());
System.out.println(isSameClass);
}
static abstract class A {
abstract void foo();
}
这里的想法是,当您创建一个新的匿名类时,您实际上是在为单个实例子键入您使用的类。这就是为什么双括号初始值设定项是个坏主意的部分原因
编辑:访问仅属于匿名类的变量。但是,如果您对反射没有意见,类似的方法可能会奏效:
try {
final Field i = first.getClass().getDeclaredField("i");
i.setAccessible(true);
System.out.println(i.getInt(first));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
这是相当混乱的,我不一定推荐它,但它确实完成了您在这里要做的事情。您可以在方法中本地定义一个新类 我在方法
main
中添加了一个新类MixA
int。为了了解它是如何工作的,这个类扩展了一个抽象类ClassA
,并实现了一个接口AInterface
,但您不需要这样做,只需要扩展或实现您需要的
因此,如果定义了类,您可以在编译时查找添加的每个方法或公共:
abstract class ClassA {
abstract void doThis();
}
interface AInterface {
public int getInternalValue();
}
public class TestAnonymousInner {
public static void main(String args[])
{
class MixA extends ClassA implements AInterface {
public int varB = 10;
@Override
public int getInternalValue()
{
return 0;
}
@Override
void doThis()
{
}
}
MixA b = new MixA();
b.getInternalValue();
b.doThis();
System.out.println(b.varB);
}
}
可以在方法中本地定义新类 我在方法
main
中添加了一个新类MixA
int。为了了解它是如何工作的,这个类扩展了一个抽象类ClassA
,并实现了一个接口AInterface
,但您不需要这样做,只需要扩展或实现您需要的
因此,如果定义了类,您可以在编译时查找添加的每个方法或公共:
abstract class ClassA {
abstract void doThis();
}
interface AInterface {
public int getInternalValue();
}
public class TestAnonymousInner {
public static void main(String args[])
{
class MixA extends ClassA implements AInterface {
public int varB = 10;
@Override
public int getInternalValue()
{
return 0;
}
@Override
void doThis()
{
}
}
MixA b = new MixA();
b.getInternalValue();
b.doThis();
System.out.println(b.varB);
}
}
我的问题是,如果我在新的匿名类中创建了一个名为“varA”的新变量,即使我将“varA”公开,我也无法像“eat”一样访问varA。@Luca,请查找编辑的部分,您甚至无法访问
eat()
如果抽象类定义中没有提到它。我的问题是,如果我在新的匿名类中创建了一个名为“varA”的新变量,即使我将“varA”公开,我也无法像“eat”一样访问varA。@Luca,请查找编辑的部分,您甚至无法访问eat()
如果抽象类定义中没有提到它。我已经编辑了我的帖子,以使事情更清楚。假设我试图从外部访问特定于匿名实例化的变量或方法。不幸的是,这是静态类型的限制。你可以在这里了解更多:啊。非常感谢您的参考!:)我编辑了我的帖子,使事情更清楚。假设我试图从外部访问特定于匿名实例化的变量或方法。不幸的是,这是静态类型的限制。你可以在这里了解更多:啊。非常感谢您的参考!:)可能重复的我想我找到了你要找的,我已经更新了我的答案。不使用反射是不可能的。嗯,是的,似乎唯一的方法是使用反射或定义类继承。可能重复的我想我找到了你要找的,我已经更新了我的答案。不使用反射是不可能的。嗯,是的,似乎唯一的方法是使用反射或定义类继承。我理解,但问题是我想访问varB,即使它没有在AClass或AInterface中定义。我理解,但问题是我想访问varB,即使它没有在AClass或AInterface中定义。