Java obtiene el método de superclase para usar el método de instancia de subclase cuando lo llama una subclase

Estoy intentando obtener un método de superclase para que se ejecute en métodos / campos de subclase cuando la subclase lo llama. Por ejemplo

public class CoffeeMachine() {
    protected int cost = 3;

    protected int getCost() {
        return cost;
    }
}

public class FancyCoffeeMachine() extends CoffeeMachine{
    protected int cost = 6;
}

main{
    FancyCoffeeMachine expensive = new FancyCoffeeMachine();
    System.out.println(expensive.getCost());
}

Me gustaría que esto imprima 6, pero imprime 3 en su lugar. Quiero hacer esto lo más SECO posible, así que estoy tratando de evitar hacer un segundo método getCost (). ¿Hay alguna forma de hacer esto? ¿Cómo puedo obtener un método de superclase para usar variables de subclase, cuando la subclase lo llama? Lo mismo sucede con los métodos: si tengo

public class makeCoffee() {
    System.out.println("Coffee cost " + this.getCost());
}

la salida será "El café cuesta 3" incluso cuando llamo a makeCoffee en una FancyCoffeeMachine. ¿Por qué es esto? ¿Cómo puedo arreglarlo? ¿O hay una mejor manera de implementar esta estructura de objeto que evita completamente este error?

Respuesta 1

La vinculación de campos no utiliza la distribución dinámica como lo hacen las llamadas a métodos virtuales. Su campo FancyCoffeeMachine.costsimplemente esconde el campo CoffeeMachine.cost.

Para lograr lo que desea (es decir, que FancyCoffeeMachine tenga un costo más alto) simplemente puede establecer un nuevo valor en el CoffeeMachine.costcampo dentro de un bloque inicializador o constructor FancyCoffeeMachine.

public class CoffeeMachine {
    protected int cost = 3;

    protected int getCost() {
        return cost;
    }
}
public class FancyCoffeeMachine extends CoffeeMachine{
    {cost = 6;} // <- sets CoffeeMachine.cost
}
Respuesta: 2

Está llamando al método getCostde la superclase (CoffeeMachine) porque no lo tiene en su subclase (FancyCoffeeMachine). Y su superclase no sabe nada sobre la subclase y su campo cost. También debe anular el método getCostpara que funcione como lo describió.

Respuesta: 3

Estoy bastante seguro de que tengo para anular getCost()el FancyCoffeeMachinetambién.

public class FancyCoffeeMachine() extends CoffeeMachine{
    protected int cost = 6;

    protected int getCost() {
        return cost;
    }
}

Pero si quisiera implementar esto, lo que haría sería hacer un resumen de CoffeeMachine como este

abstract class CoffeeMachine {
    private int cost;

    CoffeeMachine(int cost) {
        this.cost = cost;
    }

    int getCost() {
        return cost;
    }
}

y luego extenderlo en mi superclase así

class FancyCoffeeMachine extends CoffeeMachine {
    FancyCoffeeMachine(int cost) {
        super(cost);
    }
}

y llamarlo como tal

FancyCoffeeMachine fancyCoffeeMachine =  new FancyCoffeeMachine(6);
System.out.println(fancyCoffeeMachine.getCost());
Respuesta: 4

¿Ya sea que JdbcDaoSupport # getConnection () establezca una conexión nueva o simplemente obtenga la conexión del grupo?

Esta pregunta ya ha sido formulada por muchas personas, pero la solución que funcionó para ellos no funciona para mí. He probado en Android 8.1 y Android 9.0 y no puedo obtener el nombre del SSID. ...

En los casos en que el usuario haya cerrado el navegador y se haya marchado, quiero iniciar sesión cuando se agote el tiempo de espera de la sesión. Por ejemplo, como cierre de sesión inducido por el sistema en lugar de solicitud del usuario (ya tengo trabajo y ...

Estoy escribiendo un juego pequeño y necesito leer el archivo de texto, escribirlo en una matriz y luego imprimir la matriz. Mi clase para leer y devolver una matriz se ve así: import java.io. *; import java.util. *; ...