2021-05-23

【JAVA基础】一个案例搞懂类、对象、重载、封装、继承、多态、覆盖、抽象和接口概念及区别上 篇0 前言初学JAVA时,总会对一些概念一知半解,相互混淆,不明其设计的用意,如类、对象、重载、封装、继承、多态、覆盖、抽象类、接口概念。为便于理解和巩固,本文将基于一个案例及其变形,展现各个概念的定义、设计用意、使用规范和注意事项。长文警告,建议先收藏后阅读!为控制篇幅,本文将分上中下三篇讲解以上概念。上篇:讲解类、对象、构造器、重载和封装概念。中篇:讲解继承、覆盖和多态概念。下篇:讲解抽象和接口概念,以及一个综合练习。1 类(Class)、对象(Object)和构造器(Constructor)1.1 案例要求设计一个矩形的面积计算器,输入为矩形的高(height)和宽(width),输出为矩形的面积(area)。1.2 代码对JAVA的语法有最基本的了解后可以写出如下代码:class Rectangle{ //创建矩形类 public double height; //定义类的成员变量 public double width; public Rectangle() { //定义无参构造器–可省略 } public void calcuArea() { //定义类的方法–面积计算 System.out.println(“面积为:”+heightwidth); }}public class Test{ public static void main(String[] args) { Rectangle rec=new Rectangle(); //创建矩形对象–调用构造器 rec.height=1; //高度赋值 rec.width=2; //宽度赋值 rec.calcuArea(); //调用面积计算方法 }}1.3 代码分析以上代码包含以下概念:1、类(Class):类是构造对象的模板或蓝图,其由成员变量和方法构成,前者记录数据,后者记录数据的操作过程。2、对象(Object):对象是类的实例化,一个类可以有多个对象。3、构造器(Constructor):构造器是一种特殊的方法,用于对象实例化时的初始化操作。注意:构造器总是和关键字“new”一起使用。构造器的方法名必须和类名一致!任意一个类都包含至少一个构造器,当没有自定义构造器时,编译器会自动设定为无参构造器;但如果自定义了有参构造器,并需要调用无参构造器时,就必须自己手动写。构造器中,this()用于调用同一类中的其他构造方法;super()用于调用父类的构造方法。都必须位于构造方法中的第一行,且两者不能同时存在。思考:以上代码虽然实现了基本功能,但其功能不够完善,比如当用户输入的高度和宽度为字符串时,代码就会报错,那怎么才能在不给用户输入添加麻烦的情况下实现功能呢?2 重载(Overload)2.1 案例要求设计一个矩形的面积计算器,输入为矩形的高和宽(数字或者字符串输入,假定用户输入的字符串都是数值型字符串),输出为矩形的面积。2.2 代码class Rectangle{ public double height; public double width; //定义无参构造器–可省略 public Rectangle() { } //定义有参构造器1 public Rectangle(double height,double width) { this.height=height; //this指代当前对象,用于区分方法中的形参 this.weight=width; } //定义有参构造器2 public Rectangle(String height,String width) { this.height=Double.valueOf(height); this.weight=Double.valueOf(width); } public void calcuArea() { System.out.println(“面积为:”+heightwidth); }}public class Test{ public static void main(String[] args) { Rectangle rec=new Rectangle(1,2); //创建矩形对象–调用构造器1 rec.calcuArea(); //调用面积计算方法 Rectangle rec1=new Rectangle(“1”,“2”); //创建矩形对象–调用构造器2 rec1.calcuArea(); //调用面积计算方法 }}2.3 代码分析以上代码包含以下概念:重载(Overload):指类中多个方法具有相同的名字,但参数类型或返回类型不同的现象。重载的设定是为了方便用户操作,以相同的方法名实现特定的功能,同时匹配不同的参数类型以满足功能的扩展性和需求的多样性。在上面的代码中我们实现了构造器方法的重载,完美解决了用户输入多样性的问题,但重载并不局限于构造器方法,它可以适用于类中的任何方法。注意:不允许方法名和参数类型相同,但返回类型不同的情况出现,因为程序无法判断返回哪一个。方法的形参类型相同但顺序不同也构成重载,如add(double a,int b)和add(int a,double b)。思考:以上代码虽然解决了之前提出的问题,但是仍存在一个巨大的安全隐患,即用户可以直接通过“rec.height”和“rec.width”对矩形的高和宽赋值,这会导致两个我们不愿意看到的情景。一是,当用户输入非常规数值(比如-1)时,计算的结果是没有意义的;二是,后期更改程序时难以维护,比如我们后期要将height的变量类型改为String类型,那么就必须更改每一处height赋值的地方(如代码1.2)。那么,如何改进呢?3 封装(Encapsulation)3.1 案例要求设计一个矩形的面积计算器,输入为矩形的高和宽(数值输入),且数值都应大于零,输出为矩形的面积。同时要避免2.3中所述的问题。3.2 代码class Rectangle{ private double height; //私有化实例字段 private double width; public void setHeight(double height) { //定义更改器方法 if (height<0) { this.height =0; } else { this.height = height; } } public void setWidth(double width) { if (width<0) { this.width =0; } else { this.width = width; } } public double getHeight() { //定义访问器方法 return height; } public double getWidth() { return width; } public void calcuArea() { System.out.println(“面积为:”+height*width); }}public class Test{ public static void main(String[] args) { Rectangle rec=new Rectangle(); rec.setHeight(-1); //设定高 rec.setWidth(2); //设定宽 rec.calcuArea(); //读取高和宽 System.out.println(“高为:”+rec.getHeight()+" 宽为:"+rec.getWidth()); }}3.3 代码分析以上代码包含以下概念:封装(Encapsulation):通过私有化类的成员变量,并创建相应的公有化的更改器(即设定成员变量的独立方法,如setHeight)和访问器(即读取成员变量的独立方法,如getHeight)实现对成员变量的封装。设计用意:成员变量私有化的设计,使用户无法通过“rec.height”和“rec.width”对矩形的高和宽赋值与读取。更改器和访问器公有化的设计,使用户可以随意调用,实现对成员变量的赋值与读取。在更改器中我们可以设定数值规范,避免因用户的错误输入所带来的问题。在后期调试中,我们只需要改写类的成员变量类型及相应的更改器便可,无需修改每个实例化对象的相关代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值