【0】README
0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理清 java 抽象类;
0.2) 最后还阐述了 受保护域 protected 的访问属性;
【1】抽象类相关
1.1)使用 abstract关键字,这样就完全不需要实现 这个方法了
如, public abstract String getDescription(); 为了提供程序的清晰度, 包含一个或多个抽象方法的类本身必须被声明为抽象的;
abstract class Person
{
public abstract String getDescription();
}
1.2)除了抽象方法外, 抽象类还可以包含具体数据和具体方法,如,
abstract class Person
{
private String name;
public Person(String n)
{
name = n;
}
public abstract String getDescription();
public String getName()
{
return name;
}
}
Hint) 许多程序员认为,在抽象类中不能包含具体方法,建议尽量将通用的域和方法(不管抽象与否)放在超类中(不管抽象与否);
【2】扩展抽象类有两种选择:
2.1)一种是:在子类中定义部分抽象方法或抽象方法也不定义, 这样就必须将子类也标记为抽象类;
2.2)另一种是:定义全部的 抽象方法,这样一来,子类就不是抽象的了;
2.3)类即使不含有抽象方法,也可以将类声明为抽象类;
2.4)抽象类不能被实例化: 也就是说, 如果将一个类声明为 abstract, 就不能创建这个类的 对象;
Attention)需要注意: 可以定义一个抽象类的对象变量,但是它只能引用非抽象子类 的对象;
【3】看个荔枝:
abstract public class Person
{
private String name;
public Person(String n)
{
name = n;
}
abstract public String getDescription();
public String getName()
{
return name;
}
}
class Student extends Person
{
private String major;
public Student(String n, String m)
{
super(n);
major = m;
}
public String getDescription()
{
return "a student named " +
super.getName() +
" in " + major;
}
}
Attention)
- A1)有些人可能对 p.getDescription() 的调用感到困惑:请牢记,由于不能构造抽象类 Person的对象, 所以变量p 永远不会引用 Person对象, 而是引用诸如 Employee 或 Student这样的具体子类对象;
- A2)是否可以省略Person 超类中的抽象方法, 而仅仅在 Employee 和 Student 子类中定义 getDescription 方法呢? 如果这样的话, 就不能通过 变量p 调用 getDescription 方法了,编译器只允许调用在类中声明的方法;
Complementary) 受保护访问
- C1)人们希望超类中的某些方法允许被子类访问,或允许子类方法访问超类的某个域, 为此,需要把这些方法或域 声明为 protected;
C2)谨慎使用 protected属性:假设需要将设计的类提供给其他程序员使用, 而在这个类中设置了一些受保护域, 由于其他程序员可以由这个类再派生出新类, 并访问其中的受保护域。在这种情况下, 如果需要对这个类的实现进行修改, 就必须通知所有使用这个类的程序员, 这违背了 OOP 提倡的数据封装原则;
C3)下面归纳一下 java 用于控制可见性的4个访问修饰符:
- private: 仅对本类可见;
- public: 对所有类可见;
- protected: 对本包和所有子类可见;
- 默认: 对本包可见,不需要修饰符;