1、抽象类就是在普通类结构中增加抽象方法的组成。抽象类用abstract来声明。
abstract class Ab{//定义一个抽象类 public void fun(){//普通方法 System.out.println("存在方法体的方法"); } //此方法并没有方法体的声明,并且有abstract关键字,表示抽象方法 public abstract void print(); }
抽象类不能实例化
abstract class Ab{//定义一个抽象类 public void fun(){//普通方法 System.out.println("存在方法体的方法"); } //此方法并没有方法体的声明,并且有abstract关键字,表示抽象方法 public abstract void print(); } //一个子类只能继承一个抽象类,属于单继承局限 class Ab2 extends Ab{//Ab2类是Ab类的子类,并且是一个普通类 public void print(){//强制要求覆写的方法 System.out.println("Hello world!"); } } public class AbstractDemo { public static void main(String[] args) { Ab ab = new Ab2();//向上转型 ab.print(); } }
运行结果:
Hello world!
-
1. 抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
-
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
-
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现。
-
4. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
2、抽象类不能用final定义,因为抽象类必须有子类,final定义的类不能有子类。
外部抽象类不允许使用static声明,但是内部的抽象类运行使用static声明。
abstract class Abs{ //static定义的内部类属于外部类 static abstract class Abs2{ public abstract void print(); } } class X extends Abs.Abs2{ public void print(){ System.out.println("Hello"); } } public class AbstractDemo2 { public static void main(String[] args) { Abs.Abs2 a = new X(); a.print(); } }
任何情况下,要执行类中的static方法时,都可以在没有对象的时候直接调用,对于抽象类也是一样。
abstract class Abs{ public static void print(){ System.out.println("Hello"); } } public class AbstractDemo2 { public static void main(String[] args) { Abs.print(); } }
为用户隐藏不需要知道的子类:
abstract class Abst{//定义一个抽象类 public abstract void print(); private static class Abst2 extends Abst{//内部抽象类子类 public void print(){ System.out.println("Hello"); } } public static Abst getInstance(){ return new Abst2(); } } public class AbstractDemo3 { public static void main(String[] args) { //此时取得抽象类,完全不需要知道B类的存在 Abst a = Abst.getInstance(); a.print(); } }
构造方法遗留问题:
abstract class Abstr{ public Abstr(){ //2、父类构造方法 this.print(); //3、调用print()方法 } public abstract void print(); } class Abstr2 extends Abstr{ private int num =100; public Abstr2(int mun){ this.num = num; } public void print(){ //4、调用覆写后方法 System.out.println("num="+num); //num未初始化,内容是其对应数据类型的默认值 } } public class AbstractDemo4 { public static void main(String[] args) { new Abstr2(30); //1、执行构造 } }
输出结果:
num=0
public class AbstractDemo4 { public static void main(String[] args) { new Abstr2(30).print(); //1、执行构造 } } num=0 num=30
3、抽象类应用——模板设计
abstract class Action1{ public static final int EAT = 1; public static final int SLEEP =3; public static final int WORK =5; public void command(int flag){ // switch 只支持数值判断,而if支持条件判断 switch (flag){ case EAT: this.eat(); break; case SLEEP: this.sleep(); break; case WORK: this.work(); break; case EAT+WORK: this.eat(); this.work(); break; } } //因为现在不确定子类的实现是什么样的 public abstract void eat(); public abstract void sleep(); public abstract void work(); } class Robot extends Action1{ public void eat(){ System.out.println("机器人补充能量"); } public void sleep(){} public void work(){ System.out.println("机器人正在努力工作"); } } class Human extends Action1{ public void eat(){ System.out.println("人类正在吃饭"); } public void sleep(){ System.out.println("人在睡觉"); } public void work(){ System.out.println("人为了梦想在工作"); } } class Pig extends Action1{ public void eat(){ System.out.println("猪正在吃东西"); } public void sleep(){ System.out.println("猪在睡觉养膘"); } public void work(){} } public class AbstractDemo5 { public static void main(String[] args) { fun(new Robot()); fun(new Human()); fun(new Pig()); } public static void fun(Action1 action){ action.command(Action1.EAT); action.command(Action1.SLEEP); action.command(Action1.WORK); } }
运行结果:
机器人补充能量
机器人正在努力工作
人类正在吃饭
人在睡觉
人为了梦想在工作
猪正在吃东西
猪在睡觉养膘