自学内容网 自学内容网

【JAVA 笔记】06 车辆属性抽象类

要求

写出一个抽象类Car,具有Brand、PowerMode、MaxSpeed、Price四个保护属性,分别为String、String、整型和双精度浮点型,且具有公有的getPrice和getPowerMode方法(用于返回Price和PowerMode变量的值)和一个无参的抽象方法Start;以Car类为父类派生出一个子类NEV,NEV类具有属性NEDC(续航里程,为整型),且实现无参Start方法,功能是在屏幕上输出字符串:走起!然后再设计一个测试类(CarTest.java),在main方法中创建一个NEDC为800公里、Brand为BYD、PowerMode为PHEV、MaxSpeed为220公里、Price为36万NEV类的对象Whale,并执行它的Start方法。

下面是一个包含抽象类 Car 和其子类 NEV 的 Java 示例代码,以及一个测试类 CarTest 来验证这些类的功能。

抽象类 Car

首先定义一个抽象类 Car,它包含四个受保护的属性,并提供公共的 getPricegetPowerMode 方法。同时定义了一个抽象方法 Start

public abstract class Car {
    protected String brand; // 品牌
    protected String powerMode; // 动力模式
    protected int maxSpeed; // 最高速度
    protected double price; // 价格

    public Car(String brand, String powerMode, int maxSpeed, double price) {
        this.brand = brand;
        this.powerMode = powerMode;
        this.maxSpeed = maxSpeed;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public String getPowerMode() {
        return powerMode;
    }

    // 抽象方法,由子类实现
    public abstract void Start();
}

子类 NEV

接下来定义一个继承自 Car 的子类 NEV,增加一个 nedc 属性表示续航里程,并实现 Start 方法。

public class NEV extends Car {
    private int nedc; // 续航里程

    public NEV(String brand, String powerMode, int maxSpeed, double price, int nedc) {
        super(brand, powerMode, maxSpeed, price);
        this.nedc = nedc;
    }

    // 实现抽象方法
    @Override
    public void Start() {
        System.out.println("走起!");
    }

    public int getNEDC() {
        return nedc;
    }
}

测试类 CarTest

最后编写一个测试类 CarTest,在 main 方法中创建一个 NEV 类的对象,并调用它的 Start 方法。

public class CarTest {
    public static void main(String[] args) {
        // 创建一个NEV对象
        NEV whale = new NEV("BYD", "PHEV", 220, 360000, 800);
        
        // 调用Start方法
        whale.Start();
    }
}

说明

  1. 抽象类 Car:

    • 定义了品牌、动力模式、最高速度和价格四个属性。
    • 提供了获取价格和动力模式的公共方法。
    • 定义了一个抽象方法 Start,需要子类实现。
  2. 子类 NEV:

    • 继承自 Car 类。
    • 增加了一个续航里程 nedc 属性。
    • 实现了 Start 方法,输出“走起!”。
  3. 测试类 CarTest:

    • 创建了一个 NEV 类的对象,并设置了相应的属性。
    • 调用了 Start 方法来测试是否正确输出。

这样就完成了一个简单的汽车类的定义及其测试。在这个例子中,NEV 是一个新能源车,通过 Start 方法模拟启动车辆的行为。

好的,我们来详细分析一下如何设计这个程序,包括抽象类 Car、派生类 NEV 和测试类 CarTest

设计思路

1. 抽象类 Car 的设计
  • 目的:定义所有类型汽车共有的属性和行为。
  • 属性:品牌 (brand)、动力模式 (powerMode)、最高速度 (maxSpeed) 和价格 (price)。
  • 方法
    • getPrice():返回汽车的价格。
    • getPowerMode():返回汽车的动力模式。
    • Start():抽象方法,由子类具体实现,用于模拟汽车启动的行为。
2. 子类 NEV 的设计
  • 目的:定义新能源汽车特有的属性和行为。
  • 新增属性:续航里程 (nedc)。
  • 方法:实现父类 Car 中定义的抽象方法 Start(),用于模拟新能源汽车启动的行为。
3. 测试类 CarTest 的设计
  • 目的:测试 NEV 类的功能。
  • 行为:创建一个 NEV 类的实例,并调用其 Start() 方法。

代码实现

1. 抽象类 Car
public abstract class Car {
    // 受保护的属性,可以被子类访问
    protected String brand; // 品牌
    protected String powerMode; // 动力模式
    protected int maxSpeed; // 最高速度
    protected double price; // 价格

    // 构造函数
    public Car(String brand, String powerMode, int maxSpeed, double price) {
        this.brand = brand;
        this.powerMode = powerMode;
        this.maxSpeed = maxSpeed;
        this.price = price;
    }

    // 获取价格
    public double getPrice() {
        return price;
    }

    // 获取动力模式
    public String getPowerMode() {
        return powerMode;
    }

    // 抽象方法,由子类实现
    public abstract void Start();
}
2. 子类 NEV
public class NEV extends Car {
    // 新增属性,续航里程
    private int nedc;

    // 构造函数
    public NEV(String brand, String powerMode, int maxSpeed, double price, int nedc) {
        super(brand, powerMode, maxSpeed, price);
        this.nedc = nedc;
    }

    // 获取续航里程
    public int getNEDC() {
        return nedc;
    }

    // 实现抽象方法 Start
    @Override
    public void Start() {
        System.out.println("走起!");
    }
}
3. 测试类 CarTest
public class CarTest {
    public static void main(String[] args) {
        // 创建一个NEV对象
        NEV whale = new NEV("BYD", "PHEV", 220, 360000, 800);

        // 输出车辆信息
        System.out.println("品牌:" + whale.brand);
        System.out.println("动力模式:" + whale.getPowerMode());
        System.out.println("最高速度:" + whale.maxSpeed + "公里");
        System.out.println("价格:" + whale.getPrice() + "万元");
        System.out.println("续航里程:" + whale.getNEDC() + "公里");

        // 调用Start方法
        whale.Start();
    }
}

解释

  1. 抽象类 Car:

    • 定义了四个受保护的属性:brand, powerMode, maxSpeed, price
    • 提供了一个构造函数,用于初始化这些属性。
    • 提供了两个公共方法 getPrice()getPowerMode() 用于获取价格和动力模式。
    • 定义了一个抽象方法 Start(),由子类具体实现。
  2. 子类 NEV:

    • 继承自 Car 类。
    • 添加了一个私有属性 nedc 表示续航里程。
    • 提供了一个构造函数,用于初始化父类和自身的新属性。
    • 实现了 Start() 方法,输出 “走起!” 表示汽车启动。
  3. 测试类 CarTest:

    • main 方法中创建了一个 NEV 类的对象 whale
    • 输出了对象的一些基本信息。
    • 调用了 Start() 方法来模拟汽车启动。

这样我们就完成了整个程序的设计与实现。通过这种方式,我们可以很容易地扩展其他类型的汽车,只需要继承 Car 类并实现 Start() 方法即可。

完整运行代码整理

抽象类 Car

public abstract class Car {
    // 受保护的属性,可以被子类访问
    protected String brand; // 品牌
    protected String powerMode; // 动力模式
    protected int maxSpeed; // 最高速度
    protected double price; // 价格

    // 构造函数
    public Car(String brand, String powerMode, int maxSpeed, double price) {
        this.brand = brand;
        this.powerMode = powerMode;
        this.maxSpeed = maxSpeed;
        this.price = price;
    }

    // 获取价格
    public double getPrice() {
        return price;
    }

    // 获取动力模式
    public String getPowerMode() {
        return powerMode;
    }

    // 抽象方法,由子类实现
    public abstract void Start();
}

子类 NEV

public class NEV extends Car {
    // 新增属性,续航里程
    private int nedc;

    // 构造函数
    public NEV(String brand, String powerMode, int maxSpeed, double price, int nedc) {
        super(brand, powerMode, maxSpeed, price);
        this.nedc = nedc;
    }

    // 获取续航里程
    public int getNEDC() {
        return nedc;
    }

    // 实现抽象方法 Start
    @Override
    public void Start() {
        System.out.println("走起!");
    }
}

测试类 CarTest

public class CarTest {
    public static void main(String[] args) {
        // 创建一个NEV对象
        NEV whale = new NEV("BYD", "PHEV", 220, 360000, 800);

        // 输出车辆信息
        System.out.println("品牌:" + whale.brand);
        System.out.println("动力模式:" + whale.getPowerMode());
        System.out.println("最高速度:" + whale.maxSpeed + "公里");
        System.out.println("价格:" + whale.getPrice() + "万元");
        System.out.println("续航里程:" + whale.getNEDC() + "公里");

        // 调用Start方法
        whale.Start();
    }
}

说明

  1. 抽象类 Car:

    • 定义了四个受保护的属性:brand, powerMode, maxSpeed, price
    • 提供了一个构造函数,用于初始化这些属性。
    • 提供了两个公共方法 getPrice()getPowerMode() 用于获取价格和动力模式。
    • 定义了一个抽象方法 Start(),由子类具体实现。
  2. 子类 NEV:

    • 继承自 Car 类。
    • 添加了一个私有属性 nedc 表示续航里程。
    • 提供了一个构造函数,用于初始化父类和自身的新属性。
    • 实现了 Start() 方法,输出 “走起!” 表示汽车启动。
  3. 测试类 CarTest:

    • main 方法中创建了一个 NEV 类的对象 whale
    • 输出了对象的一些基本信息。
    • 调用了 Start() 方法来模拟汽车启动。

编译和运行

为了编译和运行上述代码,你需要将它们保存在三个不同的文件中:

  1. Car.java 文件中包含 Car 类。
  2. NEV.java 文件中包含 NEV 类。
  3. CarTest.java 文件中包含 CarTest 类。

然后,可以在命令行中使用以下命令编译这些类:

javac Car.java NEV.java CarTest.java

编译完成后,可以使用以下命令运行 CarTest 类:

java CarTest

运行结果应该如下所示:

品牌:BYD
动力模式:PHEV
最高速度:220公里
价格:360000.0万元
续航里程:800公里
走起!

好的,我们将进一步拓展这篇文章的内容,深入探讨面向对象编程(OOP)的核心概念,并结合具体代码示例进行详细解释。

面向对象编程的核心概念

1. 封装(Encapsulation)

封装是面向对象编程的一个基本特性,它指的是将数据和操作数据的方法捆绑在一起,形成一个整体(即对象)。封装还包括隐藏内部状态和实现细节,只暴露必要的接口给外部使用。

在代码示例中,Car 类的属性都是受保护的(protected),这意味着它们只能被类本身及其子类访问。而 getPrice()getPowerMode() 方法则提供了访问这些属性的方式,这是封装的一个典型应用。

2. 继承(Inheritance)

继承允许一个类继承另一个类的属性和方法。继承使得代码复用成为可能,并且可以建立类之间的层次关系。

在本例中,NEV 类继承了 Car 类,因此它自动获得了 Car 类的所有非私有属性和方法。此外,NEV 类还可以定义自己的新属性和方法,如 nedcgetNEDC() 方法。

3. 多态(Polymorphism)

多态是指允许不同类的对象对同一消息作出响应的能力。简单来说,就是“一种接口,多种实现”。在 Java 中,多态可以通过方法覆盖(overriding)和方法重载(overloading)来实现。

在代码示例中,Car 类定义了一个抽象方法 Start(),而 NEV 类实现了这个方法。这意味着虽然 Start() 方法在 Car 类中是抽象的,但在 NEV 类中它有了具体的实现。这就是多态的一种体现。

更深入的技术细节

1. 抽象类与接口的区别

尽管在前面的示例中我们使用了抽象类,但在某些情况下,接口可能是更好的选择。接口与抽象类的区别在于:

  • 抽象类 可以包含具体实现的方法,而接口只能包含抽象方法。
  • 接口 支持多重继承,而 Java 中的类只能继承单一的抽象类。
  • 抽象类 可以拥有构造函数,而接口不可以。

在实际应用中,如果需要强制多个类遵守相同的协议,而不关心它们的实现细节,那么接口是一个更好的选择。

2. 构造函数与初始化

NEV 类中,我们定义了一个构造函数来初始化父类的属性和自身的属性。构造函数是对象创建时被自动调用的方法,用于设置初始状态。

public NEV(String brand, String powerMode, int maxSpeed, double price, int nedc) {
    super(brand, powerMode, maxSpeed, price); // 调用父类构造器
    this.nedc = nedc;
}

这里 super 关键字用于调用父类的构造函数,确保父类的属性被正确初始化。

3. 方法覆盖与方法重载
  • 方法覆盖(Overriding) 发生在子类中,子类重写了父类的方法,以提供具体的实现。在我们的例子中,NEV 类覆盖了 Car 类的 Start() 方法。
@Override
public void Start() {
    System.out.println("走起!");
}
  • 方法重载(Overloading) 则是指在同一类中定义多个同名方法,但参数列表不同。这在当前示例中没有体现,但在实际开发中非常常见。
4. 访问修饰符的作用

在 Java 中,有四种访问修饰符:publicprotectedprivate 和默认(无修饰符,也称为包级访问)。这些修饰符决定了类、方法或属性的可见性范围。

  • public:在任何地方都可以访问。
  • protected:只有在同一包内或者子类可以访问。
  • private:只有在定义它的类内部可以访问。
  • 默认:只有在同一包内可以访问。

Car 类中,我们使用了 protected 修饰符来保护属性不被外部直接访问。

实际应用中的考虑

1. 异常处理

在实际应用中,你可能需要处理各种异常情况,比如输入非法的数据。可以通过抛出异常或进行条件检查来保证代码的健壮性。

2. 日志记录

对于复杂的系统,记录日志可以帮助跟踪程序的状态和调试问题。例如,可以在 Start() 方法中添加日志记录:

public void Start() {
    System.out.println("走起!");
    // 记录日志
    System.out.println("NEV " + getBrand() + " 已经启动.");
}
3. 国际化与本地化

如果应用程序需要支持多种语言和地区,那么就需要考虑如何在不同的环境中正确地显示信息。例如,可以使用资源文件来管理不同的语言文本。


原文地址:https://blog.csdn.net/shaozheng0503/article/details/142553420

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!