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

让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!"); }

     // 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中定义。