一个类不可能去继承一个已经实现好的类,只能继承抽象类或实现接口.
普通类就是一个完善的功能类,可以直接产生对象并且可以直接使用,里面的方法都是带有方法体 {} 的,而抽象类中最大的特点是包含了抽象方法,抽象方法是只声明而未实现(没有方法体),抽象方法定义时要使用abstract关键字,并且抽象方法一定要在抽象类中,抽象类要使用abstract关键字声明.
范例1:
abstract class A{
private String info = "hello" ;
public void print(){
System.out.println(info) ;
}
public abstract void get() ; //抽象方法:只声明,没有方法体
}
public class Demo{
public static void main(String args[]){
A a = new A() ;
}
}
运行结果:
抽象类不能直接new,原因在于一个类的对象实例化之后,可以调用类中的属性和方法,但是抽象类中的抽象方法没有方法体.
抽象类的使用原则:
1.抽象类必须有子类,使用extends继承,一个类只能继承一个抽象类;'
2.子类(如果不是抽象类),则必须覆写抽象类中的全部抽象方法;
3.抽象类对象可以使用对象的向上转型方法,通过子类来进行实例化操作.
范例2:
abstract class A{
private String info = "hello" ;
public void print(){
System.out.println(info) ;
}
public abstract void get() ; //抽象方法:只声明,没有方法体
}
class Impl extends A{
public void get(){
System.out.println("world") ;
}
}
public class Demo{
public static void main(String args[]){
A a = new Impl() ; //向上转型
a.print() ; //自己类定义
a.get() ; //子类负责实现
}
}
运行结果:
由以上代码可以发现,其与之前的继承不一样的是,抽象类定义出了子类必须要覆写的方法,而之前的类可以由选择性的决定是否需要覆写.而且抽象类实际上就比普通类多了些抽象方法而已,其他的定义和普通类完全一样.
注意点:
1.抽象类不能使用final定义,因为抽象类必须有子类,final定义的类不能有子类;
2.抽象类中可以包含构造方法.因为抽象类中出了包含抽象方法之外,还包含普通方法和属性,而属性一定要在构造方法执行完毕之后才可以进行初始化操作(←→见《构造方法》);
3.抽象类中可以不包含抽象方法,但是反过来讲,如果有抽象方法,则一定是抽象类,即使抽象类中没有抽象方法,也不能够被直接实例化.
4.外部抽象类不可以直接使用static定义,但是在内部类定义的时候可以使用static,这时这个内部的抽象类就表示了一个外部抽象类.范例3:
abstract class A{
static abstract class B{
public abstract void print();
}
}
class Impl extends A.B{
public void print(){
System.out.println("hello") ;
}
}
public class Demo{
public static void main(String args[]){
A.B b = new Impl() ;
b.print() ;
}
}
运行结果:
范例4:
现在有三种类型:狗,机器人,人
狗具备3个功能:吃,睡,跑;
机器人具备2个功能:吃,工作;
人具备4个功能:吃,睡,跑.工作;
要求设计一个程序,可以让这3类不同的类型进行工作.
abstract class Action{
public static final int EAT = 1 ;
public static final int SLEEP = 3 ;
public static final int WORK = 5 ;
public static final int RUN = 7 ;
public void order(int flag){
switch(flag){
case EAT:
this.eat() ;
break ;
case SLEEP:
this.sleep() ;
break ;
case WORK:
this.work() ;
break ;
case RUN:
this.run() ;
break ;
case EAT + SLEEP + RUN:
this.eat() ;
this.sleep() ;
this.run() ;
break ;
case EAT + WORK :
this.eat() ;
this.work() ;
break ;
case EAT + SLEEP + RUN + WORK:
this.eat() ;
this.sleep() ;
this.run() ;
this.work() ;
break ;
}
}
public abstract void eat() ;
public abstract void sleep() ;
public abstract void run() ;
public abstract void work() ;
}
class Dog extends Action{
public void eat(){
System.out.println("小狗在吃.") ;
}
public void sleep(){
System.out.println("小狗在睡.") ;
}
public void run(){
System.out.println("小狗在跑步.") ;
}
public void work(){
}
}
class Robot extends Action{
public void eat(){
System.out.println("机器人加油.") ;
}
public void sleep(){
}
public void run(){
}
public void work(){
System.out.println("机器人在工作.") ;
}
}
class Person extends Action{
public void eat(){
System.out.println("人在吃饭.") ;
}
public void sleep(){
System.out.println("人在睡觉.") ;
}
public void run(){
System.out.println("人在跑步") ;
}
public void work(){
System.out.println("人在工作.") ;
}
}
public class Demo{
public static void main(String args[]){
Action act1 = new Dog() ;
act1.order(Action.EAT + Action.SLEEP + Action.RUN) ;
Action act2 = new Robot() ;
act2.order(Action.EAT + Action.WORK) ;
Action act3 = new Person() ;
act3.order(Action.EAT + Action.SLEEP + Action.RUN + Action.WORK) ;
}
}
运行结果:
上例中,如果所有的子类想要正常完成操作,必须按照指定的方法进行覆写,而此时抽象类所起的作用就是一个类定义模板的功能.此即:模板设计模式