Java与Python中的类方法调用(一般OO问题)

2024-09-19 23:45:18 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的Java类中定义了两个search方法。它们是根据searchSpec类型区分的。我的理解是,当从某处调用search方法时,会检查searchSpec的类型,并根据该类型调用正确的search方法

现在,我已经使用抽象基类在Python中实现了这个类。GuitarSpecMandolinSpec都是从我的抽象基类继承的,它们有自己的matches方法。但是我不可能在Inventory中创建两个search方法,因为参数的类型在Python中是不相关的

这意味着在Python中,当调用Inventorysearch方法时,有可能同时包含GuitarMandolin对象的列表将返回。因此,我想知道如何获得在Python中以某种方式实现的输入的Java类型检查的相同优势,以便确保search方法只返回相同类类型的工具

这是Java类

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class Inventory {

  private List inventory;

  public Inventory() {
    inventory = new LinkedList();
  }

  public void addInstrument(String serialNumber, double price,
                            InstrumentSpec spec) {
    Instrument instrument = null;
    if (spec instanceof GuitarSpec) {
      instrument = new Guitar(serialNumber, price, (GuitarSpec)spec);
    } else if (spec instanceof MandolinSpec) {
      instrument = new Mandolin(serialNumber, price, (MandolinSpec)spec);
    }
    inventory.add(instrument);
  }

  public Instrument get(String serialNumber) {
    for (Iterator i = inventory.iterator(); i.hasNext(); ) {
      Instrument instrument = (Instrument)i.next();
      if (instrument.getSerialNumber().equals(serialNumber)) {
        return instrument;
      }
    }
    return null;
  }

  public List search(GuitarSpec searchSpec) {
    List matchingGuitars = new LinkedList();
    for (Iterator i = inventory.iterator(); i.hasNext(); ) {
      Guitar guitar = (Guitar)i.next();
      if (guitar.getSpec().matches(searchSpec))
        matchingGuitars.add(guitar);
    }
    return matchingGuitars;
  }

  public List search(MandolinSpec searchSpec) {
    List matchingMandolins = new LinkedList();
    for (Iterator i = inventory.iterator(); i.hasNext(); ) {
      Mandolin mandolin = (Mandolin)i.next();
      if (mandolin.getSpec().matches(searchSpec)) 
        matchingMandolins.add(mandolin);
    }
    return matchingMandolins;
  }
}

这是Python类的

class Inventory:
    def __init__(self):
        self.instruments: List[Union[Guitar, Mandolin]] = []

    def add_instrument(self, serial_number: str, price: float, spec: Union[GuitarSpec, MandolinSpec]):
        if isinstance(spec, GuitarSpec):
            instrument = Guitar(serial_number, price, spec)
        else:
            instrument = Mandolin(serial_number, price, spec)
        self.instruments.append(instrument)

    def get(self, serial_number) -> Union[Guitar, Mandolin, None]:
        for instrument in self.instruments:
            if instrument.serial_number == serial_number:
                return instrument
        return None

    def search(self, search_spec: Union[GuitarSpec, MandolinSpec]) -> List[Union[Guitar, Mandolin]]:
        matching_instruments = []
        for instrument in self.instruments:
            if instrument.get_spec().matches(search_spec):
                matching_instruments.append(instrument)
        return matching_instruments

Tags: 方法self类型searchreturniflistspec
1条回答
网友
1楼 · 发布于 2024-09-19 23:45:18

第一件事:在Java代码中,您使用的是原始类型和不正确的类型检查泛型。比如说,

 private List inventory;

应该是

private List<? extends Instrument> inventory;

public Inventory() {
    inventory = new LinkedList<>();
}

此外,您还使用原始迭代器并最终执行以下操作:

Guitar guitar = (Guitar)i.next();

它只会编译一个警告,但在运行时会抛出一个ClassCastException。基本上,您的问题与Python代码相同

更改原始类型后,区分工具的一种方法是根据类型和谓词对其进行过滤,例如:

inventory.stream().filter(item -> item instanceof Guitar).filter(...)

在Python中,可以使用list comprehension来过滤元素

相关问题 更多 >