在面向父类编程的过程中,抽象出来的父类具有一般化特质。父类函数只是一个抽象化的概念,只是为了在面向对象编程时统一接口服务。
example:
有时父类会定义出一些无法实现的行为:
public void call(People people){
peole.speak();
}
此函数面向父类People设计,适合所有的人类使用,但是People的子类没有被定义,People中的speak也无法具体实现。此段代码是一段通用的代码,不能等待所有子类设计完成之后再设计call函数。所以系统需要提供一种机制来定义一种不用实现的函数,这种函数称为抽象函数。
public abstract class People{ //抽象类
public abstract void speak(); //抽象函数
}
抽象函数使用abstract关键字修饰,表达了一种不完整的概念。
只有在子类实现了其中的抽象函数后,构成了一个完整的、具体的类型之后,才能使用。
public class Chinese extends People{
public void speak(){
System.out.println("中国话");
}
public static void main(String[] args){
People people = new Chinese();
people.speak();
}
}
attention:一个抽象类中,至少有一个以上的抽象函数,其中可以混合定义具体的函数。
一个类中如果没有任何抽象元素,它也可以被定义为一个抽象类型。这表示设计者不希望用户直接实例化它,只希望通过子类来实现具体的应用。
对于父类不能完全确定的实现函数,可以使用空实现体。但不建议这样做,因为调用后的执行结果什么也没有,客户可能会觉得困惑。
使用抛出异常来表示此方法没有实现:
public class People{
public void speak() throws IllegalAccessException{
throw new IllegalAccessException("没有实现,不可访问");
}
}
当用户调用此函数,系统会抛出一个异常,这样比一个空实现更友好。
总结:
(1)抽象类可以有构造方法,普通成员变量,非抽象的普通方法,静态方法,静态成员变量。
(2)抽象类中的抽象方法的访问类型可以是public、protected和默认类型。抽象类只能继承一个类。
example:
描述一个简单的树状结构:
import java.util.ArrayList;
import java.util.List;
public abstract class Node{
protected String name;
protected int data;
public abstract Node add(Node child);
}
class ConcreteNode extends Node{
private List<Node>children = new ArrayList<Node>();
public ConcreteNode(String name,int data){
this.name = name;
this.data = data;
}
public Node add(Node child){
children.add(child);
return this;
}
public static void main(Stringp[] args){
Node root = new ConcreteNode("root",0);
Node first = new ConcreteNode("first",0);
root.add(first).add(new ConcreteNode("second",2));
first.add(new ConcreteNode("third",3)).add(new ConcreteNode("fourth",4));
}
}