Java 从入门到进阶之路(十三)
在之前的文章我们介绍了一下 Java 类的 private,static,final,本章我们来看一下 Java 中的抽象类和抽象方法。
我们先来看下面一段代码:
// 根据周长求面积
class Square { // 方形类
double c; double area() { // 方形面积
return 0.0625 * c * c;
}
} class Circle { // 圆形类
double c; double area() { // 圆形面积
return 0.0796 * c * c;
}
}
在上面的代码中我们分别定义了一个方形类和圆形类,然后根据周长计算出各自的面积。咋上面的代码中可以看出这两段代码都有相同的地方,我们第一感觉就是将相同的部分单独封装成一个父类,然后通过集成的方式完成,如下:
class Shape { // 图形
double c; double area() { // 如果不 return 的话会编译错误
return 系数 * c * c; // 不同形状系数不同
} void area() { // 不会出现编译错误,但是这样写这个方法没有任何意义 }
} // 根据周长求面积
class Square extends Shape { // 方形类 } class Circle extends Shape { // 圆形类 }
在上面的代码中我们单独封装了一个 Shape 类,但是有一个问题,周长 c 是公共的没问题,但是面积 area() 方法却由于不同图形的面积系数不同,没法解决,此时就需要利用抽象方法来解决了,即在方法体前面加 abstract 关键字,如下:
class Shape { // 图形
double c; abstract double area(); // 抽象方法 --不完整 }
抽象方法的定义:
1、由 abstract 修饰;
2、只有方法的定义,没有方法的实现(大括号都没有);
但是抽象方法是不完整的,所以我们需要将类也变成抽象类,如下:
abstract class Shape { // 图形 --不完整
double c; abstract double area(); // 抽象方法 --不完整 }
抽象类的定义:
1、由 abstract 修饰;
2、包含抽象方法的类必须是抽象类;
3、抽象类不能被实例化;
4、抽象类是需要被继承的,所以子类需要:
1)重写所有抽象方法 --- 常用
2)也声明未抽象类 ---不常用
在第 4 点钟抽象类是需要被继承的,如下代码:
abstract class Shape { // 图形 --不完整
double c; abstract double area(); // 抽象方法 --不完整 } class Square extends Shape { // 编译错误,因为继承了 Shape 类,Shape 类中包含 抽象方法 } // 改进
abstract class Square extends Shape { // 不报错误,但是 Square 类也变成了抽象类 } // 改进
class Square extends Shape { // 不报错误,将 Square 类中的抽象类重写为非抽象类
double area() {
return 0.0625 * c * c;
}
}
在上面的代码中我们实现了抽象类和抽象方法,但是貌似看上去多此一举,如下:
class Shape { // 图形 只提取公共变量 c
double c;
} abstract class Shape { // 图形 --不完整
double c; abstract double area(); // 抽象方法 --不完整
}
在上面的代码中,我们完全可以只提取公共变量 周长c 就可以了,因为 area() 方法反正是要重写的,何必多此一举呢。
接下来我们看下面的需求,就是分别以 周长 c = 1,2,3 来创建三个 Square 和 Circle 类,然后找出这 6 个图形中面积最大的一个。我们首先想到的方法应该是这样:
public class HelloWorld {
public static void main(String[] args) {
Square[] squares = new Square[3];
squares[0] = new Square(1);
squares[1] = new Square(2);
squares[2] = new Square(3); Circle[] circles = new Circle[3];
circles[0] = new Circle(1);
circles[1] = new Circle(2);
circles[2] = new Circle(3); /**
* 1、找到 squares 中最大面积 sMax
* 2、找到 circles 中最大面积 cMax
* 3、比较 sMax 与 cMax 的最大值
*/ }
} class Shape {
double c;
} class Square extends Shape {
Square(double c) {
this.c = c;
} double area() {
return 0.0625 * c * c;
}
} class Circle extends Shape {
Circle(double c) {
this.c = c;
} double area() {
return 0.0796 * c * c;
}
}
在上面的代码中,我们先定义一个数组,里面存数三个周长 c = 1,2,3 的 Square,再定义一个数组,里面存放三个周长 c = 1,2,3 的 Circle,然后我们分别计算出两个数组中面积的最大值再比较出面积最大的一个,这个可以解决我们的问题,但是如果再价格六边形,就需要再定义一个数组,那么我们上面写的代码就出现了 代码重复,扩展性差,维护性差 的问题。
接下来我们用抽象类的方法来写一下:
public class HelloWorld {
public static void main(String[] args) {
Shape[] shapes = new Shape[6]; // 向上造型
shapes[0] = new Square(1);
shapes[1] = new Square(2);
shapes[2] = new Square(3);
shapes[3] = new Circle(1);
shapes[4] = new Circle(2);
shapes[5] = new Circle(3); double max = shapes[0].area(); // 先假设第一个为最大值
for(int i=1;i<shapes.length;i++){
double area = shapes[i].area();
if(area > max){
max = area;
}
}
System.out.println(max);
}
} abstract class Shape {
double c;
abstract double area();
} class Square extends Shape {
Square(double c) {
this.c = c;
} double area() {
return 0.0625 * c * c;
}
} class Circle extends Shape {
Circle(double c) {
this.c = c;
} double area() {
return 0.0796 * c * c;
}
}
在上面的代码中我们先定义了一个 Shape[] 数组,然后通过向上造型的方式向数组中分别添加 Square 和 Circle,这样就只在一个数组中比较最大值就可以了,当再添加五边形,六边形时只需要扩充 Shape[] 数组就可以了。
抽象类的意义:
1、为其子类提供一个公共的类型 -- 向上造型;
2、封装子类中的重复内容(成员变量和方法);
3、定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的。
Java 从入门到进阶之路(十三)的更多相关文章
- Java 从入门到进阶之路(二十三)
在之前的文章我们介绍了一下 Java 中的 集合框架中的Collection 的迭代器 Iterator,本章我们来看一下 Java 集合框架中的Collection 的泛型. 在讲泛型之前我们先来 ...
- Java 从入门到进阶之路(一)
写在前面:从本片文章开始,将记录自己学习 Java 的点滴路程,目标定的并不是让自己成为一个 Java 高手,而是让自己多掌握一门语言,使自己的知识面更广一些,在学习 Java 的过程中如有不对的地方 ...
- Java 从入门到进阶之路(二)
之前的文章我们介绍了一下用 IDEA 编辑器创建一个 Java 项目并输出 HelloWorld,本章我们来看一下 Java 中的变量和基本数据类型. 在这之前我们先来看一下 Java 中的关键字,这 ...
- Java 从入门到进阶之路(三)
之前的文章我们介绍了 Java 中的变量和基本数据类型,本章我们来看一下 Java 的运算符和表达式. 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操 ...
- Java 从入门到进阶之路(四)
之前的文章我们介绍了 Java 的运算符和表达式,本章我们来看一下 Java 的循环结构. 循环是程序设计语言中反复执行某些代码的一种计算机处理过程,是一组相同或相似语句被有规律的重复性进行. 循环的 ...
- Java 从入门到进阶之路(五)
之前的文章我们介绍了 Java 的循环结构,本章我们来看一下 Java 的数组 数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. 数组 - 相同数据类型的元 ...
- Java 从入门到进阶之路(六)
之前的文章我们介绍了 Java 的数组,本章我们来看一下 Java 的对象和类. Java 是一种面向对象语言,那什么是对象呢,对象在编程语言中属于一个很宽泛的概念,我们可以认为万事万物都是对象,每个 ...
- Java 从入门到进阶之路(七)
在之前的文章中我们介绍了一下 java 中的对象和类,接下来我们来看一下 Java 中的方法重载. 在显示生活中,我们肯定会遇到这样一个问题,那就是我们再商场买东西的时候在付账时的选择.如下 A:在收 ...
- Java 从入门到进阶之路(八)
在之前的文章我们介绍了一下 Java 中的重载,接下来我们看一下 Java 中的构造方法. 我们之前说过,我们在定义一个变量的时候,java 会为我们提供一个默认的值,字符串为 null,数字为 0. ...
随机推荐
- gcc在x64体系中如何传递参数,linux,mac,iOS适用
上一篇介绍了vc(windows)平台在x64体系当中,c函数的传参方式.本篇将要介绍gcc(类linux,mac)平台在x64中,c函数是如何传参的.为节约时间和篇幅,首先来定义一个有十个参数的函数 ...
- 检测当前IE浏览器的版本
检测当前IE浏览器的版本(注意:在非IE浏览器中是看不到效果的) 使用示例如下:低于IE8弹窗提示 <!--[if lte IE 8]><script>alert('您当前浏览 ...
- Windows 10上源码编译glog和gflags 编写glog-config.cmake和gflags-config.cmake | compile glog and glags on windows from source
本文首发于个人博客https://kezunlin.me/post/bb64e398/,欢迎阅读! compile glog v0.3.5 and glags on windows from sour ...
- C++程序的耦合性设计
声明:本文部分采用和参考<代码里的世界观-通往架构师之路>中内容,可以说是该书中耦合性一章的读后感,感谢该书的作者余叶老师的无私分享. 1.什么是耦合? 耦合其实就是程序之间的相关性. 程 ...
- 在SQL Server数据库中执行存储过程很快,在c#中调用很慢的问题
记录工作中遇到的问题,分享出来: 原博客地址:https://blog.csdn.net/weixin_40782680/article/details/85038281 今天遇到一个比较郁闷的问题, ...
- 使用lib-flexible.js适配移动端UI设计750px设计图
最近在和设计沟通关于设计图尺寸大小和前端实际页面尺寸大小不一致的情况,我们的UI设计是使用的iPone6的,(iphone6: 375px*667px 实际像素:750px*1334px)如果 ...
- 线程池ThreadPoolExecutor的使用方法
方法我们通过继承Thread类和实现runnable接口或者callable接口三种方式实现. 继承Thread类实际上也是实现了runnable接口,被继承的类主要是实现run()方法,通过star ...
- Java流程控制之(二)循环
目录 while循环 do..while循环 for循环 while循环和for循环基本概念--直接上代码! while循环 int i = 0; while(i<10) { System.ou ...
- GitHub 标星 1.6w+,我发现了一个宝藏项目,作为编程新手有福了!
大家好,我是 Rocky0429,一个最近老在 GitHub 上闲逛的蒟蒻... 特别惭愧的是,虽然我很早就知道 GitHub,但是学会逛 GitHub 的时间特别晚.当时一方面是因为菜,看着这种全是 ...
- python的reduce,map,zip,filter和sorted函数
一. reduce(function,Iterable),它的形式和map()函数一样.不过参数function必须有两个参数. reduce()函数作用是:把结果继续和序列的下一个元素做累积计 ...