一、为什么要有抽象类
看下面一段代码:
class 狗 { void 叫() { System.out.println("汪汪“); } } class 狼 { void 叫() { System.out.println("嗷嗷“); } }
这两个类中都有相似过程,但是过程中的内容确不相同。可以将这两个类进行抽取提升,建立一个父类。代码如下:
abstact class 犬科 { abstract void 叫(); } class 狗 extends 犬科 { void 叫() { System.out.println("汪汪"); } } class 狼 extends 犬科 { void 叫() { System.out.println("嗷嗷"); } }
将相同的属性和方法提取出来,在父类中形成一个抽象的方法,用关键字abstract表示。而抽象方法的内容是空的,具体内容在子类中实现。所以要注意的是抽象方法定义是没有花括号这个函数体。
包含有抽象方法的类称为抽象类。
抽象类特点:
1. 方法只有声明没有实现时,这个方法就是抽象方法,需要被abstract修饰。抽象方法必须定义在抽象类中,该类也必须用abstract修饰。
2. 抽象类不能被实例化,因为抽象类含有抽象方法,而抽象方法没有具体的函数体,无法实例化。
3. 抽象类必须由其子类实现其所有的抽象方法后才可以实例化,否则其子类仍然是抽象类。
抽象类可以包含构造函数,其目的不是为了构造对象,而是为了子类进行初始化。
抽象类可以没有抽象函数,其目的是为了防止此类进行实例化。AWT的适配器就是此类。
抽象类中不能出现final、private、static等关键字。
当一个抽象类中的方法都是抽象方法时,该类可用另一个形式定义和表示——接口(interface)
定义接口使用的关键字不是class,而是interface,在用javac.exe编译后,也会出现类(.class)文件。
接口中的常见成员主要有:
1. 全局常量 固定修饰符:public static final
2. 抽象方法 固定修饰符:public abstract
由此可见,接口中的成员都是公共权限。
上面的关键字可以不写,但为了可读性,建议要写上固定修饰符。
类与类之间是继承(extents)关系,所谓继承,表示子类可以直接使用父类中的某些成员。而类与接口之间是实现(implements)关系,因为接口中的所有成员方法都需要实现,不能直接用。
接口不能直接实例化,只有全部实现接口中的抽象函数的子类才能实例化,否则这个子类就是一个抽象类。
在java中不直接支技多继承,因为会出现调用的不确定性,所以java将多继承机制进行改良,在java中变成了多实现,即一个类可以实现多个接口。
java的多实现不会出现不确定性,因为在实现了多实现的子类中才会真正实现抽象方法。
interface A { public void show(); } interface B { public void show(); } class Test implements A,Z //多实现 { public void show() { System.out.println("hello"); } }
类与类之间是继承关系(单继承),类与接口之间是实现关系(可以继承一个类,实现多个接口),而接口与接口之间是继承关系(可以是多继承)。
抽象类和接口的异同点:
相同点:
都是不断向上抽取而来的。
不同点:
1. 抽象类需要被继承,而且只能单继承。
接口需要被实现,而且可以多实现。
2. 抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
接口中只能定义抽象方法,必须由子类去实现。
3. 抽象类的继承,是is a关系,在定义该体系的基本共性内容。
接口的实现是like a关系,在定义体系的额外功能。