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 中实现了这个类。 GuitarSpec
和 MandolinSpec
都继承自我的抽象基类,并且有自己的 matches
方法。但我无法在Inventory
中创建两个search
方法,因为参数的类型在Python 中是不相关的。
这意味着在 Python 中,当调用 Inventory
的 search
方法时,可能会返回包含 Guitar
和 Mandolin
对象的列表。所以,我想知道如何才能获得以某种方式在 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问题)[重复]的主要内容,如果未能解决你的问题,请参考以下文章