抽象类存在的意义,一定程度上,可以说就是继承存在的意义。因为人总是很懒的,继承这一特性能很好的满足人类懒这一特性;另一方面,继承能够将具有相同特性的类进行逻辑上的连接,也就是继承链(Inheritance Chain)。继承链的顶端是父类,底部是子类。顶端可以是抽象类,也可以是具体类;底部可以是抽象类,也可以是具体类。
下面来具体讨论下抽象类。所谓抽象类,可以很直接地理解为被abstract关键字修饰的类。下面还是看看一个直接的例子(引自Core Java):
abstract class Person{ public Person(String n){ name = n; } public abstract String getDescription(); public String getName(){ return name; } private String name; }
从这个例子中,能够得出这样的结论:抽象类中,既可以有抽象方法,也可以有具体方法或者叫非抽象方法。
进一步看下面这段代码:
abstract class Man extends Persons{ public Man(String n){ super(n); this.gender = "Male"; } public String getGender(){ return gender; } private String gender; }
这个例子很有意思。你看到这个类是抽象类,但是它的方法“全是”非抽象方法。那么可不可以把这个abstract去掉呢?答案是:不能!因为你没有具体实现父类,也就是Person类的所有抽象方法。好了,补充上面的结论:抽象类中,既可以全是抽象方法,也可以全是非抽象方法。一个继承于抽象类的子类,只有实现了父类所有的抽象方法才能够是非抽象类。
再看下面的代码:
public class AbstractTest { public static void main(String args[]){ Persons p = new Persons("Justin"); //Error } }
当你试图去实例化一个抽象类的时候,会有编译期错误。很好理解,抽象的东西无法具体化,也就是实例化。
再看下面的代码:
class Myself extends Man{ public String getDescription(){ String temp = ""; temp = "My name is"+ this.getName() +", and I am a "+ this.getGender() +"."; return temp; } }
类Myself实现了仅有的一个抽象方法,但是这个时候编译器还是会报错。为什么?把错误贴出来:Implicit super constructor Man() is undefined for default constructor. Must define an explicit constructor。意思是说类Myself的父类没有定义默认无参数的构造方法,因此Myself类必须显式地定义一个构造方法。所以,为了改正这个错误,有两个办法。一是给Man类添加默认的无参数的构造方法,但是问题来了,Person类也需要添加。二是给Myself类显式地添加一个构造方法,而且是带参数的构造方法。还是取捷径吧!看代码:
class Myself extends Man{ public Myself(String n){ super(n); } public String getDescription(){ String temp = ""; temp = "My name is "+ this.getName() +", and I am a "+ this.getGender() +"."; return temp; } }
多提一句:一般情况下还是提倡显式地实现默认无参数的构造方法。好了,现在再来重写AbstractTest类:
public class AbstractTest { public static void main(String args[]){ Persons p = new Myself("Justin"); Man m = new Myself("Justin"); Myself me = new Myself("Justin"); System.out.println(p.getDescription()); System.out.println(m.getDescription()); System.out.println(me.getDescription()); } }
输出如下:
My name is Justin, and I am a Male. My name is Justin, and I am a Male. My name is Justin, and I am a Male.
你可以看到这下,就没有问题了。但是你可能疑惑为什么Myself的实例可以赋值给Person和Man的对象呢?你可以认为是动态绑定(Dynamic Binding),多态(Polymorphism)甚至是转型(Casting)。但是这里不再多议。接下来,会简单分析和实现一个接口。
抽象类与继承

被折叠的 条评论
为什么被折叠?



