Java抽象类、抽象⽅法详解
⽬录
1. 概述
类⽤于描述现实⽣活中⼀类事物。类中有属性、⽅法等成员。
⽗类中的⽅法,被它的⼦类们重写,⼦类各⾃的实现都不尽相同。那么⽗类的⽅法声明和⽅法主体,只有声明还有意义,⽽⽅法主体则没有存在的意义了。
某种情况下,⽗类只能知道⼦类应该具备⼀个怎样的⽅法,但是不能够明确知道如何实现该⽅法。只能在⼦类中才能确定如何去实现⽅法体。例如:所有⼏何图形都应该具备⼀个计算⾯积的⽅法。但是不同的⼏何图形计算⾯积的⽅式不同。
我们把没有⽅法主体的⽅法称为抽象⽅法。Java语法规定,包含抽象⽅法的类就是抽象类。
2. 抽象⽅法
抽象⽅法:只有⽅法的声明,没有⽅法体,以分号 ; 结尾,使⽤abstract关键字修饰
定义格式:
修饰符 abstract 返回值类型⽅法名(参数列表);
代码举例:
public abstract void run();
抽象⽅法不能⽤private、final、static、native修饰
3. 抽象类
抽象类:包含抽象⽅法的类。如果⼀个类包含抽象⽅法,那么该类必须是抽象类,使⽤abstract关键字修饰
定义格式:
public abstract class 类名 {
//抽象类中可以包含变量、常量,抽象⽅法,⾮抽象⽅法
}
代码举例:
public abstract class Person {
public abstract void work();
}
抽象类的使⽤
抽象类不能实例化,不能直接创建对象。抽象类是⽤来被继承的,继承抽象类的⼦类必须重写⽗类所有的抽象⽅法。否则,该⼦类也必须声明为抽象类,使⽤abstract关键字修饰
抽象类也是类,因此原来类中可以有的成员,抽象类都可以有,那么抽象类不能直接创建对象,为什么还有构造器呢?供⼦类调⽤,⼦类创建对象时,需要为从⽗类继承的属性初始化。
抽象类不能使⽤final修饰
public class Teacher extends Person {
public void work() {
System.out.println("讲课");
}
}
public class AbstractClassTest {
public static void main(String[] args) {
// 创建⼦类对象
Teacher t = new Teacher();
// 调⽤run⽅法
t.work();
}
}
输出结果:
讲课
此时的⽅法重写,是⼦类对⽗类抽象⽅法的完成实现,我们将这种⽅法重写的操作,叫做实现⽅法。
实现:去掉abstract关键字,加上⽅法体{...}
抽象类注意事项:
1. 抽象类不能创建对象,如果创建,编译⽆法通过⽽报错。只能创建其⾮抽象⼦类的对象。
理解:假设创建了抽象类的对象,调⽤抽象的⽅法,⽽抽象⽅法没有具体的⽅法体,没有意义。
2. 抽象类中,可以有构造⽅法,是供⼦类创建对象时,初始化⽗类成员使⽤的。
理解:⼦类的构造⽅法中,有默认的super(),需要访问⽗类构造⽅法。
3. 抽象类中,可以有成员变量。
理解:⼦类的共性的成员变量 , 可以定义在抽象⽗类中。
4. 抽象类中,不⼀定包含抽象⽅法,但是有抽象⽅法的类必定是抽象类。
理解:未包含抽象⽅法的抽象类,声明为抽象类⽬的就是不想让使⽤者创建该类的对象,通常⽤于某些特殊的类结构设
计。
5. 抽象类的⼦类,必须重写抽象⽗类中所有的抽象⽅法,否则,编译报错。除⾮该⼦类也是抽象类。
理解:假设不重写所有抽象⽅法,则类中可能包含抽象⽅法。那么创建对象后,调⽤抽象的⽅法,没有意义。
抽象类与普通类的区别
抽象类使⽤abstract修饰;普通类没有abstract修饰
抽象类不能实例化;普通类可以实例化
抽象类可以包含抽象⽅法,也可以包含⾮抽象⽅法;普通类不能有抽象⽅法
4. abstract关键字
可以⽤来修饰的结构:类、⽅法,不能⽤来修饰变量、代码块、构造器
不能和 abstract ⼀起使⽤的修饰符
外部类可⽤修饰符:abstract、final,两种访问修饰符:public和缺省。其中abstract和final不能⼀起修饰类
⽅法可⽤修饰符:4种访问修饰符,static、final、abstract、native。不能共存的:
private,abstract不⾏因为private不能被重写
static,abstract不⾏因为static不能被重写
final,abstract不⾏因为final不能被重写
native,abstract不⾏因为都没有⽅法体,不知道是什么情况,会有歧义
5. 抽象类简单案例
5.1案例介绍
某IT公司有多名员⼯,按照员⼯负责的⼯作不同,进⾏了部门的划分(研发部员⼯、维护部员⼯)。研发部根据所需研发的内容不同,⼜分为JavaEE⼯程师、Android⼯程师;维护部根据所需维护的内容不同,⼜分为⽹络维护⼯程师、硬件维护⼯程师。
公司的每名员⼯都有他们⾃⼰的员⼯编号、姓名,并要做它们所负责的⼯作。
⼯作内容:
JavaEE⼯程师:员⼯号为xxx的 xxx员⼯,正在研发淘宝⽹站
Android⼯程师:员⼯号为xxx的 xxx员⼯,正在研发淘宝⼿机客户端软件
⽹络维护⼯程师:员⼯号为xxx的 xxx员⼯,正在检查⽹络是否畅通
硬件维护⼯程师:员⼯号为xxx的 xxx员⼯,正在修复打印机
请根据描述,完成员⼯体系中所有类的定义,并指定类之间的继承关系。进⾏XX⼯程师类的对象创建,完成⼯作⽅法的调⽤。
5.2 案例分析
根据上述部门的描述,得出如下的员⼯体系图:
根据员⼯信息的描述,确定每个员⼯都有员⼯编号、姓名、要进⾏⼯作。则,把这些共同的属性与功能抽取到⽗类中(员⼯类),关于⼯作的内容由具体的⼯程师来进⾏指定。
创建JavaEE⼯程师对象,完成⼯作⽅法的调⽤
5.3 ⽰例代码
定义员⼯类(抽象类)
public abstract class Employee {
private String id; // 员⼯编号
private String name; // 员⼯姓名
public String getId() {
returnid;
}
publicvoid setId(String id) {
this.id = id;
}
public String getName() {
returnname;
}
抽象类的使用
publicvoid setName(String name) {
this.name = name;
}
//⼯作⽅法(抽象⽅法)
public abstract void work();
}
定义研发部员⼯类Developer 继承员⼯类Employee
public abstract class Developer extends Employee {
}
定义维护部员⼯类Maintainer 继承员⼯类Employee
public abstract class Maintainer extends Employee {
}
定义JavaEE⼯程师继承研发部员⼯类,重写⼯作⽅法
public class JavaEE extends Developer {
@Override
public void work() {
System.out.println("员⼯号为 " + getId() + " 的 " + getName() + " 员⼯,正在研发淘宝⽹站");
}
}
定义Android⼯程师继承研发部员⼯类,重写⼯作⽅法
public class Android extends Developer {
@Override
public void work() {
System.out.println("员⼯号为 " + getId() + " 的 " + getName() + " 员⼯,正在研发淘宝⼿机客户端软件");
}
}
定义Network⽹络维护⼯程师继承维护部员⼯类,重写⼯作⽅法
public class Network extends Maintainer {
@Override
public void work() {
System.out.println("员⼯号为 " + getId() + " 的 " + getName() + " 员⼯,正在检查⽹络是否畅通"); }
}
定义Hardware硬件维护⼯程师继承维护部员⼯类,重写⼯作⽅法
public class Hardware extends Maintainer {
@Override
public void work() {
System.out.println("员⼯号为 " + getId() + " 的 " + getName() + " 员⼯,正在修复打印机");
}
}
在测试类中,创建JavaEE⼯程师对象,完成⼯作⽅法的调⽤
public class Test {
public static void main(String[] args) {
//创建JavaEE⼯程师员⼯对象
JavaEE ee = new JavaEE();
//设置该员⼯的编号
ee.setId("111111");
//设置该员⼯的姓名
ee.setName("张伟");
//调⽤该员⼯的⼯作⽅法
ee.work();
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。