Dúvida em herança

Uma dúvida bem básica desta vez, porque eu nao mexo muito com herança.
Tenho um tipo ItemCardapio que possui, dentre outros, um Double preço.
Tenho um tipo ItemPizza que extende ItemCardapio e tem um HashMap<String, Double> preço, porque cada pizza tem mais de um preço (de acordo com tamanhos) e é a unica coisa que muda pros outros itens.
No ItemPizza temos o setPreço(String key, Double preço) e o getPreço(String key) como get e set.
Eu implementei uma List<ItemCardapio> para mandar pro adapter, e pensava assim poder jogar o ItemPizza na lista quando o item fosse pizza, mas quando eu faço ItemCardapio item = new ItemPizza() e depois tento setar o preço, ele enxerga apenas os metodos da classe pai. Tentei usar o @override mas ele nao reconhece pq as assinaturas são diferentes.
Eu pensava que por eu instanciar o item como um ItemPizza, ele reconheceria os metodos dessa classe.
O que houve de errado? Que dia da faculdade eu faltei?

ItemCardapio item = new ItemPizza();

Como a classe declarada foi ItemCardapio, somente métodos declarados desta classe estarão disponíveis.
Caso sobrescreva o método em itemPizza será chamado o método sobrescrito.
Como você mesmo disse as assinaturas são diferentes portanto neste caso não é possível chama-lo.

Então quer dizer que, como as assinaturas são diferentes e a classe declarada é a pai, eu nunca vou poder usar um metodo da classe filha? Qual a vantagem de se declarar pai e instanciar filho entao?

De forma direta não.

Dê uma olhada nestes exemplos.
http://www.javaprogressivo.net/2012/10/Polimorfismo-em-Java–o-que-e-pra-que-serve-como-e-onde-usar.html

Tem também a apostila f11 da caelum dá uma olhada nela.
http://www.caelum.com.br/apostila-java-orientacao-objetos/heranca-reescrita-e-polimorfismo/

Se mudar a assinatura do método na classe filha aí não será sobrecarga e sim um método novo.

Acredito que a utilização do pattern Hook Method cairia como uma luva!

-Sua classe pai seria abstrata, aonde existiria um método getValor abstrato.
-A classe pai teria um método com uma lógica padrão que chamaria o getValor. Aí é só estabelecer a lógica para instanciar a classe que entende a classe pai abstrata.

Abs!

Eu tb pensei nisso, mas eu ja havia resolvido declarando a classe filha. A lista aceitou numa boa. Tava perguntando pra aprender mesmo. Obrigado.

Voltei com mais duvida :wink:
Os itens tem alguns atributos em comum como nome, descrição, etc. e alguns especificos, a pizza que tem 4 preços, um para cada tamanho;
Em certos momentos eu vou precisar te-los todos agrupados em uma lista e em outros, dividi-los mais de acordo com seu tipo para mexer em seus atributos.
Tentei fazer uma classe abstrata pai e extender cada tipo mas não manjo muito de herança, não sei o que declarar e instanciar na classe abstrata e o que declarar e instanciar nas filhas, quando criar uma lista da classe pai, quando criar uma lista da classe filha, quando declarar classe pai e instanciar filha, quando declarar filha e instanciar filha, etc, e isso esta me gerando alguns erros.
Por exemplo, eu nao sei se devo criar uma classe abstrata pai e herdar os tipo dela, ou ter uma classe que generaliza os itens do cardapio e herdar o item pizza dela. Não sei se devo declarar todos os atributos na(s) classe(s) pai ou declarar os especificos nas filhas.
Por um momento eu havia deixado alguns metodos como abstract (os que mexem com o(s) preço(s)) pra implementar apenas nos filhos, mas aí aconteceu que eu descobri que é preciso implementar todos os metodos abstract, sendo assim, não há motivo pra minha subclasse que representa bebida sobrescrever e implementar a classe getPreço_P() que pega o valor da pizza.
São esses varios detalhes que me fazem ficar perdido. Eu nem mesmo sei se seria correto criar uma entidade para cada tipo de produto ou apenas 2 entidades porque a unica diferença é entre a pizza e os demais itens.
Qualquer ajuda é bem vinda.

Update:
Só um exemplo da minha noobisse. Tenho a classe ItemCardapio e a ItemCardapio_Pizza que extende ela e tem os 4 Double representando os preços e os 4 get e set.
Para generalização, o meu ItemPedido contém um atributo do tipo ItemCardapio, e de maneira analoga, o meu ItemPedido_Pizza extende o ItemPedido.
Aqui chega o problema, no meu ItemPedido_Pizza eu tenho o um metodo que seta o preço do pedido de acordo com o tamanho setado no ItemCardapio_Pizza. Mas como ele herda de ItemCardapio e este não conhece os getPreço_P, getPreço_M e etc, não tenho como fazer esse calculo e assim fazer uso da herança.
Se eu crio uma nova variavel do tipo ItemCardapio_Pizza com o mesmo nome, estarei posteriormente referenciando a da classe pai e não a da filha. Se eu criar com o nome diferente, perde o sentido da herança e eu nem vou poder reaproveitar o codigo da superclasse. Realmente to perdido nesse paradigma.
Por favor, alguem me da uma dica.

Update 2:
Eu estava pensando aqui, se eu implementar os 4 double e os seus get e set na classe pai, daria certo, é só eu dar override na filha e pronto.
Mas, se eu tiver tudo que eu preciso assim na classe pai, onde diabos esta a vantagem em herdar a classe?
Pelo que eu estou vendo, eu não ganho absolutamente nada em fazer Pai p = new filho(), a não ser o codigo do construtor e MAIS NADA.

Cara, você tá se enrolando porque tá usando herança onde não cabe (normal, é difícil modelar objetos mesmo). Penso que o mais adequado seria usar composição nesse caso.

Eu dividiria a sua classe em ItemCardapio e SubItemCardapio e amarraria o preço sempre em um sub-item. Assim, cada ItemCardapio pode possuir 1, 2, quantos sub-itens forem necessários sem a necessidade de criar uma subclasse para isso. Assim, você joga caracaterísticas comuns aos sub-itens em ItemCardapio, e características específicas em SubItemCardapio.

Pode dar um exemplo mais pratico? Tipo explicando onde declarar o que, onde instanciar o que, onde herdar o que?