java 抽象类学习_Java 抽象类(学习 Java 编程语言 045)

如果将一个类声明为 abstract,那么这个类就是抽象类。抽象类可以包含抽象方法、字段和具体方法。抽象类不能被实例化,但抽象类的对象变量可以引用了一个非抽象子类的实例。

如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用性,可能更加抽象。从某种角度看,祖先类更有一般性,人们只将它作为派生其他类的基类,而不是用来构造你想使用的特定的实例。例如,考虑扩展 Employee 类层次结构。员工是一个人,学生也是一个人。下面扩展我们的类层次结构来加入类 Person 和类 Student。下图显示了这三个类之间的继承关系。

ae139e778f02

Person 及其子类的继承图

Person.java

public abstract class Person {

public abstract String getDescription();

private String name;

public Person(String name) {

this.name = name;

}

public String getName() {

return this.name;

}

}

Employee.java

public class Employee extends Person {

private double salary;

private LocalDate hireDay;

Employee(String name, double salary, int year, int month, int day) {

super(name);

this.salary = salary;

hireDay = LocalDate.of(year, month, day);

}

public double getSalary() {

return salary;

}

public LocalDate getHireDay() {

return hireDay;

}

public String getDescription() {

return String.format("an employee with a salary of $%.2f", salary);

}

public void raiseSalary(double byPercent) {

double raise = salary * byPercent / 100;

salary += raise;

}

}

Student.java

public class Student extends Person {

private String major;

public Student(String name, String major) {

super(name);

this.major = major;

}

public String getDescription() {

return String.format("a student majoring in " + major);

}

}

为什么要那么麻烦提供这样一个高层次的抽象呢?每个人都有一些属性,如姓名。学生与员工都有姓名属性,因此通过引入一个公共的超类,我们就可以把 getName 方法放在继承层次结构中更高的一层。

现在,在增加一个 getDescription 方法,它可以返回对一个人的简短描述。例如:

an employee with a salary of $5,000.00

a student majoring in computer science

在 Employee 类和 Student 类中实现这个方法很容易。但是在 Person 类中应该提供什么内容呢?除了姓名之外,Person 类对这个人一无所知。当然,可以让 Person.getDescription() 返回一个空字符串。不过还有一个更好地方法,就是使用 abstract 关键字,这样就完全不需要实现这个方法了。

public abstract String getDescription();

为了提高程序的清晰度,包含一个或多个抽象方法的类本身必须被声明为抽象的。

public abstract class Person

{

...

public abstract String getDescription();

}

除了抽象方法之外,抽象类还可以包含字段和具体方法。例如,Person 类还保存着一个人的姓名,另外有一个返回姓名的具体方法。

public abstract class Person {

public abstract String getDescription();

private String name;

public Person(String name) {

this.name = name;

}

public String getName() {

return this.name;

}

}

提示: 许多程序员认为,在抽象类中不能包含具体方法。建议尽量将通用的字段和方法(不管是否是抽象的)放在超类(不管是否是抽象类)中。

抽象方法充当着占位方法的角色,它们在子类中具体实现。

扩展抽象类可以有两种选择:

在子类中保留抽象类中的部分或所有抽象方法仍未定义,这样就必须将子类也标记为抽象类。

定义全部的抽象方法,这样一来,子类就不是抽象的了。

即使不含抽象方法,也可以将类声明为抽象类。

抽象类不能被实例化。也就是说,如果将一个类声明为 abstract,就不能创建这个类的对象。

可以定义一个抽象类的对象变量,但是这样一个变量只能引用非抽象子类的对象。例如:

Person p = new Student("Vince Vu", "Economics");

这里的 p 是一个抽象类型 Person 的变量,它引用了一个非抽象子类 Student 的实例。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值