In the Java class below two search
methods are defined. They are differentiated based on searchSpec
type. My understanding is, when the search
method is called from somewhere, it is checked what is the type of searchSpec
and depending on that type the correct search
method is invoked.
Now, I have implemented this class in Python using abstract base classes. Both GuitarSpec
and MandolinSpec
are inheriting from my abstract base class, and have their own matches
method. But I don't have the possibility to create two search
methods in the Inventory
because the type of the arguments are irrelevant in Python.
That means in Python when the search
method of Inventory
is invoked, there is a possibility that a list containing both Guitar
and Mandolin
objects would return. So, I like to know how can I get the same advantage of Java type checking of inputs somehow implemented in Python, so that I can ensure the search
method returns only instruments of the same class type.
This is the Java class
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;
}
}
This is the Python class
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