深入解析Java编程中的抽象类
Java程序用抽象类(abstract class)来实现自然界的抽象概念。抽象类的作用在于将许多有关的类组织在一起,提供一个公共的类,即抽象类,而那些被它组织在一起的具体的类将作为它的子类由它派生出来。抽象类刻画了公有行为的特征,并通过继承机制传送给它的派生类。在抽象类中定义的方法称为抽象方法,这些方法只有方法头的声明,而用一个分号来代替方法体的定义,即只定义成员方法的接口形式,而没有具体操作。只有派生类对抽象成员方法的重定义才真正实现与该派生类相关的操作。
在各子类继承了父类的抽象方法之后,再分别用不同的语句和方法体来重新定义它,形成若干个名字相同,返回值相同,参数列表也相同,目的一致但是具体实现有一定差别的方法。抽象类中定义抽象方法的目的是实现一个接口,即所有的子类对外都呈现一个相同名字的方法。抽象类是它的所有子类的公共属性的集合,是包含一个或多个抽象方法的类。使用抽象类的一大优点就是可以充分利用这些公共属性来提高开发和维护程序的效率。对于抽象类与抽象方法的限制如下:
(1)凡是用abstract 修饰符修饰的类被称为抽象类。凡是用abstract修饰符修饰的成员方法被称为抽象方法。
(2)抽象类中可以有零个或多个抽象方法,也可以包含非抽象的方法。
(3)抽象类中可以没有抽象方法,但是,有抽象方法的类必须是抽象类。
(4)对于抽象方法来说,在抽象类中只指定其方法名及其类型,而不书写其实现代码。
(5)抽象类可以派生子类,在抽象类派生的子类中必须实现抽象类中定义的所有抽象方法。
(6)抽象类不能创建对象,创建对象的工作由抽象类派生的子类来实现。
(7)如果父类中已有同名的abstract方法,则子类中就不能再有同名的抽象方法。
(8)abstract不能与final并列修饰同一个类。
(9)abstract 不能与private、static、final或native并列修饰同一个方法。
Java语言规定,当一个类里面有抽象方法的时候,这个类必须被声明为抽象类。
子类继承父类时,如果这个父类里面有抽象方法,并且子类觉得可以去实现父类的所有抽象方法,那么子类必须去实现父类的所有抽象方法,如:
/** * 子类Dog继承抽象类Animal,并且实现了抽象方法enjoy * @author gacl * */ class Dog extends Animal { /** * Dog类添加自己特有的属性 */ public String furColor; public Dog(String n, String c) { super(n);//调用父类Animal的构造方法 this.furColor = c; } @Override public void enjoy() { System.out.println("狗叫...."); } }
这个父类里面的抽象方法,子类如果觉得实现不了,那么把就子类也声明成一个抽象类,如:
/** * 这里的子类Cat从抽象类Animal继承下来,自然也继承了Animal类里面声明的抽象方法enjoy(), * 但子类Cat觉得自己去实现这个enjoy()方法也不合适,因此它把它自己也声明成一个抽象的类, * 那么,谁去实现这个抽象的enjoy方法,谁继承了子类,那谁就去实现这个抽象方法enjoy()。 * @author gacl * */ abstract class Cat extends Animal { /** * Cat添加自己独有的属性 */ public String eyeColor; public Cat(String n, String c) { super(n);//调用父类Animal的构造方法 this.eyeColor = c; } }
这里的子类Cat从抽象类Animal继承下来,自然也继承了Animal类里面声明的抽象方法enjoy(),但子类Cat觉得自己去实现这个enjoy()方法也不合适,因此它把它自己也声明成一个抽象的类,那么,谁去实现这个抽象的enjoy方法,谁继承了子类,那谁就去实现这个抽象方法enjoy()。如:
/** * 子类BlueCat继承抽象类Cat,并且实现了从父类Cat继承下来的抽象方法enjoy * @author gacl * */ class BlueCat extends Cat { public BlueCat(String n, String c) { super(n, c); } /** * 实现了抽象方法enjoy */ @Override public void enjoy() { System.out.println("蓝猫叫..."); } }
完整的测试代码如下:
package javastudy.summary; /** * 父类Animal * 在class的前面加上abstract,即声明成这样:abstract class Animal * 这样Animal类就成了一个抽象类了 */ abstract class Animal { public String name; public Animal(String name) { this.name = name; } /** * 抽象方法 * 这里只有方法的定义,没有方法的实现。 */ public abstract void enjoy(); } /** * 这里的子类Cat从抽象类Animal继承下来,自然也继承了Animal类里面声明的抽象方法enjoy(), * 但子类Cat觉得自己去实现这个enjoy()方法也不合适,因此它把它自己也声明成一个抽象的类, * 那么,谁去实现这个抽象的enjoy方法,谁继承了子类,那谁就去实现这个抽象方法enjoy()。 * @author gacl * */ abstract class Cat extends Animal { /** * Cat添加自己独有的属性 */ public String eyeColor; public Cat(String n, String c) { super(n);//调用父类Animal的构造方法 this.eyeColor = c; } } /** * 子类BlueCat继承抽象类Cat,并且实现了从父类Cat继承下来的抽象方法enjoy * @author gacl * */ class BlueCat extends Cat { public BlueCat(String n, String c) { super(n, c); } /** * 实现了抽象方法enjoy */ @Override public void enjoy() { System.out.println("蓝猫叫..."); } } /** * 子类Dog继承抽象类Animal,并且实现了抽象方法enjoy * @author gacl * */ class Dog extends Animal { /** * Dog类添加自己特有的属性 */ public String furColor; public Dog(String n, String c) { super(n);//调用父类Animal的构造方法 this.furColor = c; } @Override public void enjoy() { System.out.println("狗叫...."); } } public class TestAbstract { /** * @param args */ public static void main(String[] args) { /** * 把Cat类声明成一个抽象类以后,就不能再对Cat类进行实例化了, * 因为抽象类是残缺不全的,缺胳膊少腿的,因此抽象类不能被实例化。 */ //Cat c = new Cat("Catname","blue"); Dog d = new Dog("dogname","black"); d.enjoy();//调用自己实现了的enjoy方法 BlueCat c = new BlueCat("BlueCatname","blue"); c.enjoy();//调用自己实现了的enjoy方法 } }