Java基础课 | 图形的面积(类的使用、面向对象的三大特性——封装、继承、多态)

Java基础课 | 图形的面积(类的使用、面向对象的三大特性——封装、继承、多态)

Java基础


一个类包含:

  1. 属性(成员变量),表示类的静态特征
  2. 方法(成员方法),表示类的动态行为

访问修饰符指定了成员变量的可见性和访问权限

常用的修饰符包括
- private(私有,只能在类内部访问)
- public(公共,可以从任何地方访问)
- protected(受保护,可以在类内部和子类中访问)

基本写法

public class Person {
  // 成员变量的定义:访问修饰符 数据类型 变量名
  private String name;
  
  // 构造方法
  // 是一种特殊类型的成员方法,在创建对象时自动调用,通常用于为成员变量赋初始值
  // 无参构造函数
  public Person() { // 在构造函数中进行初始化
      age = 20;
      name = "zs";
  }
  // 带参数的构造函数
  public Person(String name) {
    this.name = name;
  }
  
  // 成员方法的定义
  // 访问修饰符 返回类型 方法名(参数列表) {
  //     方法体
  // }
  public void sayHello() {
    
  }
  
  // 主方法,程序的入口
  public static void main(String[] args) {
    // 创造一个 Person 对象
    Person person1 = new Person("Tom");
    // 调用对象的方法
    person1.sayHello();
  }
}

抽象类

在建立类时,有的时候会有一些比较抽象的概念,比如形状, 它们创建实例对象并没有什么意思,形状既没有一个特定的type值,也无法计算具体的面积,这时候,我们就会将其定义为抽象类。

抽象类使用abstract来声明,并且不能实例化,类中包含一些通用的属性和方法。

abstract class Shape {
    
}

抽象方法是一种没有具体的方法,只有方法的声明,没有方法体,并且只能存在于抽象类中。也使用abstract来声明。

// 抽象类 Shape
abstract class Shape {
    // 抽象方法: 没有具体的实现,只是定义了方法名称、参数和返回类型,具体的实现由子类提供。
    public abstract double calculateArea();
}

面向对象的三大特性

封装

主要目的:保证数据的安全性。通过封装,隐藏对象中一些不希望被外部所访问到的属性或方法,具体分为两步:

  1. 将对象的属性名,修改访问修饰符为private, 这样就只能在内部类中访问,其他类访问不了。
  2. 提供gettersetter来获取和设置对象的属性
public class Circle {
      // 1. 将属性名,设置为私有的
    private int radius;

    // 构造函数
    public Circle(int radius) {
        setRadius(radius);
    }

    // 2. 定义set方法,设置属性(若希望属性只读,可去掉)
	// 设置半径,包括数据验证
	public void setRadius(int radius) {
  	  if (radius > 0) {
  	      this.radius = radius;
  	  } else {
   	     System.out.println("半径必须为正数");
  	  }
	}

    // 2. 定义get方法,获取属性(若希望属性不能被外部访问,可去掉)
    public int getRadius() {
        return radius;
    }
}

通过上面的设置,我们可以在外部代码中安全的访问和修改半径的值,这就是封装的思想,将对象的状态隐藏在对象内部,然后提供受控的接口来进行交互

继承

采用“继承”的方式,使得一个类获取到其他类中的属性和方法。在定义类时,可以在类名后使用extends指定当前类的父类(超类), 子类可以直接继承父类中的所有属性和方法,从而避免编写重复性的代码,此外我们还可以对子类进行扩展

继承的格式如下:

class A{  
    
}
class B extends A{
    
}

类A为父类,extends表示继承,即类 B 继承 类 A, 子类 B 继承父类 A 之后,就获取了父类中声明的所有的属性和方法,并且可以声明自己的属性和方法,实现功能的拓展。

例如

abstract class Shape {
    // 定义属性 type
    protected String type;
    // 定义方法CalculateArea,用来计算图形面积,方法体为空
    public double CalculateArea();
 
    // 构造方法
    public Shape(String type) {
        this.type = type;
    }
}

// extends表示继承,即Circle类继承自Shape类
class Circle extends Shape {
    private int radius;
    public Circle(String type, int radius) {
        super(type); // 调用父类的构造方法,传递 type属性
        this.radius = radius;
    }
    
    // 重写父类的求面积方法
    @Override
    public double CalculateArea() {
        return 3.14 * radius * radius;
    }
}

方法的重写:要求子类中的方法(方法名、参数类型和个数、返回类型)必须与父类中的方法相同,然后子类会调用自己的方法而不是父类的同名方法。

多态

指,虽然方法名称相同,但实际调用的方法是根据对象的类型动态确定的

例:

// 创建 Shape 类型,指向 Circle 对象
Shape myCircle = new Circle(5);
// 虽然是Shape类型,但是调用方法时根据对象本身的类型来处理
double circleArea = myCircle.calculateArea();
System.out.println("圆形的面积:" + circleArea);

// 创建 Shape 类型,指向 Rectangle 对象
Shape myRectangle = new Rectangle(4, 6);
// 虽然是Shape类型,但是调用方法时根据对象本身的类型来处理
double rectangleArea = myRectangle.calculateArea(); 
System.out.println("长方形的面积:" + rectangleArea);

具有两种形式:

  1. 编译时多态(静态多态):类有基类和子类,最初,我们可能不知道应该使用哪个类,所以使用基类来调用方法。
  2. 运行时多态(动态多态):程序运行的时候,会根据对象实际的类来调用相应的方法。

一个Java文件中,只能有一个public类,并且文件名必须和该类名匹配。

题目


题目描述
考虑一个简单的图形类层次结构,包括基类 Shape 和两个派生类 Rectangle 和 Circle。每个类都有一个用于计算面积的方法。你的任务是编写一个程序,根据输入数据创建一个图形对象,然后计算并输出其面积。
输入描述
输入包括多行,每行包含一个图形的描述。 描述的第一个单词是图形类型(“rectangle"或"circle”),然后是与该图形相关的参数。 对于矩形,参数是宽度和高度,对于圆形,参数是半径。输入以单词"end"结束。
输出描述
对于每个图形描述,输出其类型和面积。使用两位小数点精度输出面积。

程序编写


import java.util.ArrayList;
import java.util.Scanner;
// 定义抽象类 Shape
abstract class Shape {
    protected String type;

    public abstract double CalculateArea();

    public String GetType() {
        return type;
    }
}

class Rectangle extends Shape {
    private int width;
    private int height;

    public Rectangle(int width, int height) {
        this.type = "Rectangle";
        this.width = width;
        this.height = height;
    }

    public double CalculateArea() {
        return width * height;
    }
}

class Circle extends Shape {
    private int radius; // 将半径修改为整数类型

    public Circle(int radius) {
        this.type = "Circle";
        this.radius = radius;
    }

    public double CalculateArea() {
        return 3.14 * radius * radius;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        ArrayList<Shape> shapes = new ArrayList<>();

        while (true) {
            String inputLine = scanner.nextLine();
            String[] data = inputLine.split(" ");
            String shapeType = data[0];

            // 处理不同类型的输入
            if (shapeType.equals("end")) {
                break;
            }

            if (shapeType.equals("rectangle")) {
                int width = Integer.parseInt(data[1]);
                int height = Integer.parseInt(data[2]);
                shapes.add(new Rectangle(width, height)); // 添加 Rectangle 对象
            } else if (shapeType.equals("circle")) {
                int radius = Integer.parseInt(data[1]); // 将半径解析为整数
                shapes.add(new Circle(radius)); // 添加 Circle 对象
            }
        }

        // 不同类型调用同一个方法,根据类型的不同处理逻辑也不同
        for (Shape shape : shapes) {
            System.out.printf("%s area: %.2f%n", shape.GetType(), shape.CalculateArea());
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值