Hola, código bien trabajado. A continuación una serie de observaciones.
Dado que el ejercicio pretendía servir para usar herencia, es más lógico resolver este ejercicio definiendo tres subclases que hereden de la clase ProductoCongelado, en lugar de definir un atributo para indicar el tipo de producto congelado.
Para hacer uso de la herencia hubiera sido bueno que, además de los constructores, en algún método se reutilizara código. Puede verse un ejemplo en
https://www.aprenderaprogramar.com/foros/index.php?topic=2959.0 donde el método public void muestraDatosProducto() reutiliza código de las superclases en las subclases.
En la clase EnvioDeProductos no estás trabajando con objetos a la hora de añadir objetos a la lista de productos, y trabajar con objetos es algo que siempre debemos tener en mente en la programación Java.
Para añadir productos a la lista estás usando
public void addLista(String nomProd, int lote, String xPais, TipoDeProducto tipoProducto, Calendar fechaEnvasado, Calendar fechaCaducidad)
Estos productos tal y como los estás creando pueden carecer de cierta información. Por ejemplo, si es un producto congelado le faltaría la temperatura de mantenimiento
Si trabajas con objetos lo más natural sería haber usado esta forma:
public void addLista (Producto productoAnnadido)
Así ya estás trabajando directamente con objetos. El método recibiría como parámetro un objeto. Eso es algo muy frecuente en Java, con lo que debemos acostumbrarnos a trabajar.
Saludos