抽象的类方法该如何调用?

想要化简一下代码,该如何实现?希望能具体点

import java.util.Scanner;

abstract class Plane {

    int jy;
    int js;
    float wy;
    int hc;
    int psg;
//    如果要用以下的构造方法,在主方法中如何调用输入?
//    public Plane(int jy, int js, float wy, int hc, int psg) {
//        super();
//        this.jy = jy;
//        this.js = js;
//        this.wy = wy;
//        this.hc = hc;
//        this.psg = psg;
//    }

    public abstract void display();
}

class Fighter extends Plane {

    
    public void display() {

        System.out.println("This is a fighter!");
    }

    private int dd;

    public void setDd(int dd) {

        this.dd = dd;
    }

    public int getDd() {

        return dd;
    }

    @Override
    public String toString() {
        return jy + " " + js + " " + wy + " " + hc + " " + psg + " " + dd;
    }

}

class Bomber extends Plane {

    public void display() {

        System.out.println("This is a bomber!");
    }

    private int zd;

    public void setZd(int zd) {

        this.zd = zd;
    }

    public int getZd() {

        return zd;
    }

    public String toString() {

        return jy + " " + js + " " + wy + " " + hc + " " + psg + " " + zd;
    }
}

public class oj1417 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);
        Fighter fit = new Fighter();
        Bomber bmb = new Bomber();
        while (sc.hasNext()) {

            char c = sc.next().charAt(0);
            if (c == 'f') {

//                fit.jy = sc.nextInt();
//                fit.js = sc.nextInt();
//                fit.wy = sc.nextFloat();
//                fit.hc = sc.nextInt();
//                fit.psg = sc.nextInt();
//                fit.setDd(sc.nextInt());
//               想要省去上面繁琐的fit.对象,下面的形式该如何实现?
                Plane p2 = new Fighter();
                p2.Plane(sc.nextInt(),sc.nextInt(),sc.nextFloat(),sc.nextInt(),sc.nextInt());
                fit.display();
                System.out.println(fit);
            }
            if (c == 'b') {

                bmb.jy = sc.nextInt();
                bmb.js = sc.nextInt();
                bmb.wy = sc.nextFloat();
                bmb.hc = sc.nextInt();
                bmb.psg = sc.nextInt();
                bmb.setZd(sc.nextInt());
                bmb.display();
                System.out.println(bmb);

            }
        }
        sc.next();
    }
}


  • 子类 要 有对应的构造方法,并在子类的构造方法中 调用 super 先初始化父类【即调用父类的构造方法】
  • 参考如下:
import java.util.Scanner;

abstract class Plane {
    int jy;
    int js;
    float wy;
    int hc;
    int psg;

    public Plane(int jy, int js, float wy, int hc, int psg) {
        this.jy = jy;
        this.js = js;
        this.wy = wy;
        this.hc = hc;
        this.psg = psg;
    }

    public abstract void display();
}

class Fighter extends Plane {


    public Fighter(int jy, int js, float wy, int hc, int psg) {
        super(jy, js, wy, hc, psg);
    }

    public void display() {

        System.out.println("This is a fighter!");
    }

    private int dd;

    public void setDd(int dd) {

        this.dd = dd;
    }

    public int getDd() {

        return dd;
    }

    @Override
    public String toString() {
        return jy + " " + js + " " + wy + " " + hc + " " + psg + " " + dd;
    }

}

class Bomber extends Plane {

    public Bomber(int jy, int js, float wy, int hc, int psg) {
        super(jy, js, wy, hc, psg);
    }

    public void display() {

        System.out.println("This is a bomber!");
    }

    private int zd;

    public void setZd(int zd) {

        this.zd = zd;
    }

    public int getZd() {

        return zd;
    }

    public String toString() {

        return jy + " " + js + " " + wy + " " + hc + " " + psg + " " + zd;
    }
}

public class oj1417 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            char c = sc.next().charAt(0);
            if (c == 'f') {
                Plane fighter = new Fighter(sc.nextInt(), sc.nextInt(), sc.nextFloat(), sc.nextInt(), sc.nextInt());
                fighter.display();
                System.out.println(fighter);
            }
            if (c == 'b') {
                Plane fighter = new Bomber(sc.nextInt(), sc.nextInt(), sc.nextFloat(), sc.nextInt(), sc.nextInt());
                fighter.display();
                System.out.println(fighter);
            }
        }
        sc.next();
    }
}

参考GPT和自己的思路:

抽象类的方法可以通过继承该抽象类的子类中的具体实现来调用。例如,在代码中, Fighter 和 Bomber 类都继承了 Plane 类,并且实现了抽象方法 display()。因此,可以创建 Fighter 和 Bomber 类的对象,然后调用它们的 display() 方法。

如果想要省去上面繁琐的对象调用形式,可以通过创建 Plane 类的子类对象,并在创建时使用参数化构造函数,将输入参数直接传递给 Plane 类的成员变量。例如,在代码中可以这么修改:

if (c == 'f') {
    Fighter p2 = new Fighter();
    p2.jy = sc.nextInt();
    p2.js = sc.nextInt();
    p2.wy = sc.nextFloat();
    p2.hc = sc.nextInt();
    p2.psg = sc.nextInt();
    p2.setDd(sc.nextInt());
    p2.display();
    System.out.println(p2);
}

这样就省去了创建 Plane 类对象以及调用其构造函数的步骤,可以直接在 Fighter 类中使用输入参数。

参考GPT和自己的思路:

首先,抽象类不能直接被实例化,只能通过子类来实现。在代码中,大概意思是用户输入‘f’,即为创建一个Fighter对象,而在Fitghter类中,并没有实现父类Plane的构造方法,所以可以在main方法中使用多态创建一个Plane对象,再通过调用子类的set方法对变量进行初始化。但是需要注意的是,在创建对象时不能像普通类一样直接调用构造方法初始化变量,而是需要调用对应的set方法,因为抽象类没有构造方法。具体实现如下:

if (c == 'f') {
    Plane p2 = new Fighter();
    p2.setJy(sc.nextInt());
    p2.setJs(sc.nextInt());
    p2.setWy(sc.nextFloat());
    p2.setHc(sc.nextInt());
    p2.setPsg(sc.nextInt());
    ((Fighter) p2).setDd(sc.nextInt()); // 强制类型转换,调用子类的set方法
    p2.display();
    System.out.println(p2);
}

在这样的实现中,我们可以看到通过多态创建了一个Plane对象,并成功对其属性进行了初始化,同时我们还使用了强制类型转换将其转化为Fighter类型,以便调用子类的setDd方法对其私有变量进行初始化。这样就可以省去重复创建对象的步骤,简化了代码。