1 目录及资源索引
2 主要内容
本节课主要内容如下:
- 抽象函数的语法特征;
- 抽象类的语法特征;
- 抽象类的作用;
老师:“类是抽象的,对象是具体的;比类更具体的是抽象类;抽象的东西是有好处的,不容易错。”
3 基本概念
3.1 抽象函数
什么是抽象函数?
抽象函数,是用 abstract 修饰的函数;是只有函数的定义,没有函数体的函数。
例如:
abstract void fun();
代码举例如下:
class Person
{
String name;
int age;
void introduce()
{
System.out.println("我的名字是" + name + ",我的年龄是" + age);
}
abstract void eat(); // 抽象函数
}
上述代码,编译运行结果如下:
大概意思就是,里边定义了抽象函数,但是这个类不是一个抽象类,那什么是抽象类呢?
3.2 抽象类
使用 abstract 定义的类就叫做抽象类;
抽象类有如下特征:
- 抽象类不能够生成对象;
- 如果一个类当中包含有抽象函数,那么这个类必须被声明为抽象类;
- 如果一个类当中没有抽象函数,那么这个类也可以被声明为抽象类;
这个感觉跟C++中的虚函数有点像,父类中没有函数体,是一个虚函数,需要子类中复写。
另外需要注意的是:抽象类不能实例化对象, 否则意味着可以调用其中的抽象函数,而抽象函数是没有函数体的。自己尝试改了一下代码,编译后错误如下:
老师:“抽象类天生就是用来当爹的,天生就是用来当做父类的,子类可以实例化对象。”
哈哈,跟老师上课,老师的讲课风格还是很幽默的。
如果子类直接继承是抽象类的父类,如下直接写是不可以的
class Chinese extends Person
{
}
编译后,错误如下:
解决方法有两个
- 把子类 Chinese 变成抽象类,但是需要注意抽象类不能实例化对象,看上图下边的错误;
- 第二种就是把父类的抽象函数复写;
如果定义一个类,由于各种原因,不想让他生成对象,就可以把它设置为一个抽象类。
抽象类 基本等同于 基类,就是用来被继承的类。
4 抽象类可以有构造函数吗?
有两个基本的概念:
- 抽象类不能生成对象;
- 构造函数用于生成类的对象;
看到上述两个条件,可能很自然的就认为抽象类没有构造函数,下边用代码实际演示一下。
抽象类 Person 代码如下:
abstract class Person
{
Person()
{
System.out.println("Person的构造函数!");
}
String name;
int age;
void introduce()
{
System.out.println("我的名字是" + name + ",我的年龄是" + age);
}
abstract void eat(); // 抽象函数
}
子类 Chinese 代码如下:
class Chinese extends Person
{
Chinese()
{
System.out.println("Chinese的构造函数");
}
void eat()
{
System.out.println("用筷子吃饭");
}
}
存放主函数的类 Test,代码如下:
class Test
{
public static void main(String args[])
{
// Person p = new Person();
// p.introduce();
Chinese c = new Chinese();
Person p = c; // 向上转型
p.eat();
}
}
上述代码编译运行结果如下:
由上图可得答案是:抽象类也是有构造函数的,为子类调用的时候,做准备。
老师:“生成子类的时候,一定会先调用父类的构造函数。”
自我理解:之前课上讲过,所有的类都有构造函数,就算不写,编译器也会默认创建一个。如果此处抽象类没有构造函数,那就和这个结论相悖。
5 总结
- 抽象函数就是没有函数体的函数;
- 抽象类使用 abstract 来定义;
- 抽象类不能生成对象,但是却可以拥有构造函数。
- 抽象函数,抽象类的出现,为子类继承提供了很大的方便,相当于有了一个顶层框架;