Java_抽象类

3.8、抽象类(核心)

3.8.1 、抽象类的基本概念

         普通类就是一个完善的功能类,可以直接产生对象并且可以使用,里面的方法都是带有方法体的,而抽象类之中最大的特点是包含了抽象方法,而抽象方法是只声明而未实现(没有方法体)的方法,而抽象方法定义的时候要使用abstract关键字完成,而抽象方法一定要在抽象类之中,抽象类要使用abstract关键字声明。

范例:定义一个抽象类

abstract class A {

         private String info = "Hello World ." ;

         public void print() {

                   System.out.println(info) ;

         }

         public abstract void get() ;      // 只声明没有方法体

}

范例:错误的使用 —— 直接实例化对象

public class Test {

         public static void main(String args[]) {

                   A a = new A () ;  // Test.java:10: 错误: A是抽象的; 无法实例化

         }

}

思考:为什么抽象类对象不能够直接new?

         一个类的对象实例化之后,可以调用类中的属性和方法,但是抽象类之中的抽象方法没有方法体,如果这样直接调用,那么不就乱了吗。

抽象类的使用原则:

         · 抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类;

         · 子类(如果不是抽象类)则必须覆写抽象类之中的全部抽象方法;

         · 抽象类对象可以使用对象的向上转型方式,通过子类来进行实例化操作。

范例:使用抽象类

abstract class A {

         private String info = "Hello World ." ;

         public void print() {

                   System.out.println(info) ;

         }

         public abstract void get() ;    // 只声明没有方法体

}

class Impl extends A {

         public void get() {

                   System.out.println("Hello MLDN .") ;

         }

}

public class Test {

         public static void main(String args[]) {

                   A a = new Impl() ;        // 向上转型

                   a.print() ;    // 自己类定义

                   a.get() ;       // 子类负责实现

         }

}

         通过以上的一个程序,现在就可以清楚的发现,与之前类的继承不一样的是,抽象类定义出了子类必须要覆写的方法,而之前的类子类可以有选择性的来决定是否需要覆写。而且可以发现,抽象类实际上就比普通类多了一些抽象方法而已,其他的定义和普通类完全一样。如果把普通类比喻成一盘炒熟的菜,那么抽象类就是一盘半成品。

关于抽象类的若干种疑问?

         · 抽象类能否使用final定义?

                   不能,因为抽象类必须有子类,final定义的类太监类,不能有子类;

         · 抽象类之中能否包含构造方法?

可以,因为抽象类之中除了包含抽象方法之外,还包含了普通方法和属性,而属性一定要在构造方法执行完毕之后才可以进行初始化操作;

         · 抽象类之中能否不包含抽象方法?

可以,抽象类之中可以没有抽象方法,但是反过来讲,如果有抽象方法,则一定是抽象类,即使抽象类之中没有抽象方法,也不能够被直接实例化;

         · 抽象类能否使用static声明?

abstract class A {

         private String info = "Hello World ." ;

         static abstract class B {// 外部类

                   public abstract void print() ;

         }

}

class Impl extends A.B {

         public void print() {

                   System.out.println("Hello MLDN .") ;

         }

}

public class Test {

         public static void main(String args[]) {

                   A.B b = new Impl() ;

                   b.print() ;

         }

}

         如果定义的是外部抽象类,则不能够使用static声明,可是如果定义的是内部抽象类,那么这个内部的抽象类使用了static声明之后,就表示是一个外部的抽象类。

3.8.2 、抽象类的应用 —— 模板设计模式(体会)

         下面首先通过一个简单的程序来分析一下,例如:现在有三种类型:狗、机器人、人;

                   · 狗具备三种功能:吃、睡、跑;

                   · 机器人具备两个功能:吃、工作;

                   · 人具备四个功能:吃、睡、跑、工作。

         现在就要求设计一个程序,可以让这三类不同的类型,进行工作。现在给出的三个类实际上并没有任何的联系,唯一的联系就是在于一些行为上。

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 Test {

         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) ;

         }

}

         所有的子类如果要想正常的完成操作,必须按照指定的方法进行覆写才可以,而这个时候抽象类所起的功能就是一个类定义模板的功能。

原文地址:https://www.cnblogs.com/guwenren/p/3016611.html