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

Posted

技术标签:

【中文标题】Java与Python中的类方法调用(一般OO问题)[重复]【英文标题】:class method invocation in Java versus Python (General OO question) [duplicate] 【发布时间】:2020-06-10 16:51:12 【问题描述】:

在下面的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

【问题讨论】:

【参考方案1】:

首先要做的事:在 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 来过滤元素。

【讨论】:

以上是关于Java与Python中的类方法调用(一般OO问题)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

pb调用jar包的方法

ABAP中我用OO ALV,调用方法SET_TABLE_FOR_FIRST_DISPLAY 后,为何没有保存格式按钮?

PHP怎么调用其他类的方法

python 中的类

JAVA中的OOA.OOD.OOP有啥区别?

UML中的类图关系