当前位置: 首页 > 知识库问答 >
问题:

Avro模式中的多态性和继承

饶元章
2023-03-14

有没有可能编写一个Avro schema/IDL来生成一个Java类,或者扩展一个基类,或者实现一个接口?似乎生成的Java类扩展了< code > org . Apache . avro . specific . specificrecordbase 。所以,工具可能是正确的选择。但是,我不知道这是否可能。

我看过一些示例,其中包含在每个特定架构中定义显式“类型”字段的建议,其关联性大于继承语义。

我在工厂类和代码的其他部分大量使用基类,比如< code >

另一个次要问题:您可以使用IDL仅定义没有协议定义的记录吗?我认为答案是否定的,因为编译器抱怨缺少协议关键字。

感谢帮助!谢谢。

共有3个答案

杨君之
2023-03-14

我发现这个问题也有类似的问题。在我的例子中,我只需要将标记接口强加给某些类型(以便以后区分特定的类)。感谢您的回答,我更深入地研究了record.vm模板的结构。我发现可以在. avsc定义JSON中定义"javaAnnoection":"my.full.AnnotationName"key。然后将@my.full.AnnotationName添加到生成的类中。

诚然,这个解决方案最终并不是建立在标记界面上的,尽管对于我来说已经足够好了,保持模板不变是一个很大的优势。

强承望
2023-03-14

我希望这将有助于其他人,如果我写在这里,我已经为这个案例创建了maven插件-https://github.com/tunguski/interfacer.

它检查自动生成的类,并检查它们是否符合特定包中类路径上的接口。如果是,接口将被添加到该类中。它与通用接口一起工作,至少在我必须处理的基本例子中是这样。

该插件不是avro特定的,可以作为生成的代码后处理器使用,因此也可以在其他情况下使用。

<!-- 
  post process avro generated sources and add interfaces from package
  pl.matsuo.interfacer.showcase to every generated class that has 
  all methods from specific interface
 -->
<plugin>
    <groupId>pl.matsuo.interfacer</groupId>
    <artifactId>interfacer-maven-plugin</artifactId>
    <version>0.0.6</version>
    <executions>
        <execution>
            <configuration>
                <interfacesDirectory>${project.basedir}/src/main/java</interfacesDirectory>
                <interfacePackage>pl.matsuo.interfacer.showcase</interfacePackage>
            </configuration>
            <goals>
                <goal>add-interfaces</goal>
            </goals>
        </execution>
    </executions>
</plugin>
// src/main/java manually defined interface
public interface HasName {
  String getName();
}

// target/generated-sources/avro
public class Person {

  String name;

  public String getName() {
    return name;
  }
  // [...]
}

public class Company {

  String name;

  public String getName() {
    return name;
  }
  // [...]
}

// after this plugin run

// target/generated-sources/avro
public class Person implements HasName {

  String name;

  public String getName() {
    return name;
  }
  // [...]
}

public class Company implements HasName {

  String name;

  public String getName() {
    return name;
  }
  // [...]
}
花博厚
2023-03-14

我找到了一个更好的方法来解决这个问题。查看Avro中的Schema生成源,我发现内部类生成逻辑使用Velocity模式来生成类。

我修改了< code>record.vm模板来实现我的特定接口。有一种方法可以使用maven构建插件中的< code>templateDirectory配置来指定velocity目录的位置。

我还改用了< code>SpecificDatumWriter而不是< code>reflectDatumWriter。

<plugin>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-maven-plugin</artifactId>
   <version>${avro.version}</version>
   <executions>
    <execution>
      <phase>generate-sources</phase>
      <goals>
        <goal>schema</goal>
      </goals>
      <configuration>
         <sourceDirectory>${basedir}/src/main/resources/avro/schema</sourceDirectory>
         <outputDirectory>${basedir}/target/java-gen</outputDirectory>
         <fieldVisibility>private</fieldVisibility>
         <stringType>String</stringType>
         <templateDirectory>${basedir}/src/main/resources/avro/velocity-templates/</templateDirectory>
       </configuration>
    </execution>
  </executions>
</plugin>
 类似资料:
  • X:我有一个不相关的类似容器的对象(向量、映射、树、...)的集合,处理不同不相关类型的对象。这些容器中对象的生命周期在它们的某些子集之间共享。我有一个负责它们同步的对象。我能想到的同步类的最简单实现是有一个指针的向量,其中将是一个为我要管理的所有类似容器的对象实现公共接口的类。但并不是所有的都像容器一样。它们可以用作容器,但是让它们继承一个通用的基类感觉很奇怪,我害怕它会非常强烈地耦合我的设计。

  • 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。 比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印: class Animal(object): def run(self):

  • 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。 比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印: class Animal(object): def run(self):

  • 问题内容: 继承和多态都构成IS- A关系吗?在运行时发生继承和“重写”多态性而在编译时发生“过载”多态性是真的吗?我之所以这样问,是因为许多论坛似乎给出了相互矛盾且常常令人困惑的答案。 谢谢! 问题答案: 对于问题的第一部分,我认为维基百科提供了一个很好的定义: 在面向对象的程序设计中,子类型多态或包含多态是类型理论中的一个概念,其中名称可以表示许多不同类的实例,只要它们与某个公共超类相关即可。

  • 在面向对象编程中,当我们已经创建了一个类,而又想再创建一个与之相似的类,比如添加几个方法,或者修改原来的方法,这时我们不必从头开始,可以从原来的类派生出一个新的类,我们把原来的类称为父类或基类,而派生出的类称为子类,子类继承了父类的所有数据和方法。 让我们看一个简单的例子,首先我们定义一个 Animal 类: class Animal(object): def __init__(self,

  • 我正在做一个关于继承和多态性的练习,我有3个独立的分支,我的主类,一个超级动物类和一个子猫类。我已经在Animal和Cat类中制作了重载构造函数,getters和setters以及toString()方法。我想我有继承部分。现在我需要创建2个动物对象引用,两者都是Cat的实例,例如:一个是名为Tobbie的Siamese类型。 有人能给我一个这些对象引用的例子吗?您可以看到我在那里的Main类中尝