参考教材:《Java核心技术 卷一》
前言
第一篇博客讲了Java的一些基础语法,第二篇博客讲了Java面向对象的一些特性,比如类
和对象
, 还有java 三大特性 封装
,继承
,多态
, 这篇博客将继续学习java的其他的重要特性。
抽象类和抽象方法:
上一篇我们在讲继承的时候,讲到我们将几种车的共同特征抽取出来放在一个父类里,但是我现在把车的范围扩大,扩大到所有的代步工具,包括电瓶车、自行车等等。所以,原来的父类已经不能满足要求了,必须要让父类变得更加通用,让父类拥有所有车的共同特征,比如都能驾驶。这个时候,父类就很抽象了,它不能描绘出具体的对象,所以抽象类不能实例化(不能new)。声明抽象类很简单,用abstract
修饰类即可,判断一个类是不是抽象类也就是看类没有被abstract
修饰。
有抽象类就会有抽象方法(这句话意思是说abstract可以修饰类,也可以修饰方法。抽象类中不一定有抽象方法)。抽象方法只能存在抽象类中,即如果你在一个类中声明了抽象方法,那么这个类也必须声明为抽象类。抽象方法声明的时候,不需要具体的实现,
public abstract class Person{
//定义了一个名为getName,返回值类型为 String 的方法
//不需要加{},也不需要在{}里写具体实现
//具体实现是子类的事情
public abstract String getName();
}
抽象类教程:抽象类
单独的抽象类一般是不具有什么实际意义的,因为抽象类中的抽象方法没有具体的实现,也不能实例化。所以抽象类的特性注定了它只能作为一个父类,让子类来继承,并重写(或者说实现)父类的抽象方法。
这样做的目的是什么呢?就笔者个人理解而言:是为了提高代码的复用,之前说过,抽象类是更高程度的抽象,所以不同的子类会有不同的实现,这部分定义成抽象方法,成为一种规范或者协议,由子类自己去实现。但是也会由通用的行为或者逻辑,这部分就可以在抽象类中实现,从而避免不同的子类中都包含重复的代码,达到了代码代码的复用。
接口(interface)
首先强调,接口不是一个类
,接口主要是用来描述类有什么功能的,但不用给出 每个功能的具体实现。 从功能上来说,接口
和抽象类
是非常类似的。所以在很多情况下,接口和抽象类都是可以相互代替的。之所以 java设计者们又辛苦引入了接口
这个概念,是因为 java 里的类是不支持多继承的,就是一个类最多有一个父类,比如一个People 类继承(extends)了Teacher类,就不能再继承Manager类了。Java不支持多继承是因为 多继承会让语言本身变得非常复杂(比如C++),效率也会降低。
那问题来了,如果我非要继承两个类怎么办呢?这种情况下,java 就引入了 接口
这个概念,接口不是类
,一个类可以实现多个接口。实际上,接口可以提供多继承的大多数好处,同时还避免了多重继承的复杂性。
接口教程:接口
=============2020年11月16日14点48分更新
面试的时候被问到一个问题:抽象类和接口在使用上有什么区别?
- 从语法上来看,一个类能继承一个类,但是可以实现多个接口;抽象类中可以有成员属性,但接口中只能定义常量,
- 在使用的时候,一般用抽象类来表示 “是什么”,是事物的本质,是名词,如Person抽象类;而用接口来表示 **“能做什么”**是形容词或者动词,如PlayFootball接口
异常(Exception)处理
在理想状态下,用户输入的数据都是正确的,打开的文件一定存在,程序运行不会出现bug(笑。。
但。。这是不可能滴。在我们程序实际运行过程中,总会发生一些这样或者那样的问题,比如 用户输入错误,或者内部数组越界等等都有可能发生。
另外,如果用户在使用程序时因为程序出现错误,而使得某些操作没有完成,程序应该
- 返回到一种安全的状态,并能够让用户执行一些其他的命令,或者
- 运行用户保存所有操作的结果,并以妥善的形式终止程序。
对于程序运行过程中可能出现的异常,java 提供了一种 异常处理
的错误捕获机制。
异常的教程:异常处理
在教程中,列出了很多异常的种类,但是实际上你只需要了解即可,不用强行去背。
只需要掌握try catch及finally的使用以及会手动抛异常即可。在实际开发中,很难精确的捕获可能存在的异常。因此我们常常在catch捕获Exception类,因为Exception是所有异常的父类,能捕获到所有的异常。
//主动抛一个异常 及 异常的捕获
public static void main(String[] args) {
try {
throw new Exception("抛出异常");// new一个异常 然后抛出(throw),括号里的字符串是对这个异常的简要说明,可以不写
} catch (Exception e) {
e.printStackTrace();
System.out.println("捕获异常");
}
}finally{
...//该部分可省略
}
此外,java的异常处理机制还有一个特殊的用法—跳出深层递归
。有一次需要实现一个走迷宫的程序,当时笔者因为没学到栈的知识,就用了递归的方法来实现,然后笔者就遇到一个问题,找到迷宫的终点后,如果一次性跳出递归,而不是用return 逐层返回? 然后笔者发现了手动抛异常跳出递归的方法:在需要跳出递归的地方,抛一个异常,就直接跳到catch块里了。。不过这算是一个剑走偏锋的技巧,不太推荐使用,在这里笔者只是单纯的分享一下。
到这里,实际上基础的java语法都学得差不多了,如果只是想简单了解java这门语言的同学,恭喜你,你成功入门了。但对于想深入学习java或者以后想当java 工程师的同学来讲,这仅仅是开始。java还要很多很多高级的特性,反射,lambda表达式,集合,多线程等等等。后续笔者会继续更新相关教程笔记