zoukankan      html  css  js  c++  java
  • 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) ;

             }

    }

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

  • 相关阅读:
    Leetcode 126.单词接龙II
    Leetcode 125.验证回文串
    Leetcode 124.二叉树中的最大路径和
    Leetcode 123.买卖股票的最佳时机III
    Leetcode 122.买卖股票的最佳时机II
    西子凌波回复集5(网友整理版)
    西子凌波回复集4(网友整理版)
    西子凌波回复集3(网友整理版)
    K杀(逻辑-标准-规则)
    西子凌波49:2018年11月29日微博解盘提示
  • 原文地址:https://www.cnblogs.com/guwenren/p/3016611.html
Copyright © 2011-2022 走看看