抽象类、内部抽象类、模板设计算法

抽象类的定义与使用
定义: 抽象类只是在普通类的基础上扩充了一些抽象方法而已。
抽象方法:

  • 只声明未定义的方法(没有方法体)
  • 所有抽象方法要求使用abstract来定义,并且抽象方法所在类必须用abstract来定义,表示抽象类。

抽象类的使用原则:

  • 所有抽象类必须有子类(abstract与final不能同时使用,是因为final声明的类不能有子类);
  • 抽象类的子类必须覆写抽象类的所有抽象方法,前提是这个子类不在是一个抽象类,如果是子类是一个抽象类,可以不全覆写父类抽象方法(abstract与private不能同时使用);
  • 如果抽象类需要实例化对象,必须通过子类向上转型为其实例化(抽象类无法创建实例化对象)
abstract class Person   //抽象类
{
    private String name;
    abstract public void fun1(); //抽象方法
    //abstract public void func2();  //两个抽象方法必须全覆写
}
class Student extends Person
{
    public void fun1()  //重写抽象方法
    {
        System.out.println("子类继承抽象类");
    }
}
public class  Abstract
{
    public static void main(String[] args)
    {
        Person p=new Student(); //向上转型
        p.fun1();  //调用的子类中被覆写的fun1();
    }
}

抽象类的相关规定
1.抽象类允许提供构造方法,并且子类也遵循对象实例化流程,先调用父类构造方法而后调用子类构造方法。
对象实例化操作包括:

  • 进行类加载
  • 进行类对象的空间开辟
  • 进行类对象的属性初始化(构造方法)
/////面试题
abstract class Person   //抽象类
{
    public Person() //3.调用父类构造
    {
        this.fun1(); //4.调用fun1,发现父类中fun1为抽象类,就调子类中覆写的fun1
    }
    abstract public void fun1(); //抽象方法
   
}
class Student extends Person
{
    private int num=100; //7.调子类构造时初始化属性变为100
    public Student(int num)  //2.调用子类构造
    {
        this.num=num; //赋值后num变为30
    }
    public void fun1() //5.此时还没有调子类构造,属性是在调构造函数时初始化,所以此时还没有初始化属性
    {
        System.out.println(this.num); // 6.没有初始化,属性默认值为0
    }
}
public class  Abstract
{
    public static void main(String[] args)
    {
        new Student(30);//1.实例化子类对象  结果为0
        new Student(30).fun1();  //结果为0 30 ,因为先调了父类构造,所以有0
    }
}

2.抽象类中允许不定义任何的抽象方法,但是此时抽象类依然无法直接创建实例化对象。

**图片**

3.abstract不能与final一起使用:abstract定义类必须有子类,final定义类不能有子类;
abstract不能与private一起使用:abstract定义方法必须被重写,private定义方法在子类不可见。

内部抽象类
子类可以只覆写父类的直接抽象方法,不管父类内部类抽象方法;如果需要重写父类内部类抽象方法,可以在子类中定义一个父类内部抽象类的子类来重写:

abstract class Person
{
    public abstract void fun1();
    abstract class  B
    {
        public abstract void fun2();
    }
}
class Student extends Person
{
    public void fun1()  //对父类直接抽象方法覆写
    {
    }
    class C extends B //重新定义一个子类
    {
        public void fun2()
        {          
        }
    }
}

模板设计算法
模板设计算法基于抽象类,核心是封装算法。模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供具体实现。

模板(模板方法)模式:
在一个方法中定义一个算法的骨架,并将一些具体步骤延迟到子类实现。模板模式使得子类可以在不改变算法结构的基础上,重新定义算法中的某些步骤。
如下列的咖啡因饮料:咖啡和茶都有相同的步骤:煮沸水、泡咖啡或者浸泡茶、向咖啡或茶添加东西、将饮料倒入杯中,这四个步骤咖啡和茶都有,即是相同的算法结构,那么就可以把这四个步骤定义在一个算法模板中,不同的步骤子类重写:

import java.util.Scanner;

abstract class CaffeineBerverage  //父类是咖啡因饮料
{
    //模板方法 声明为final:只允许子类使用,不允许覆写
    final void prepareRecipe()
    {
        boilWater();
        brew();
        if(customerWantsCondiments())
        {
             addCondiments();
        }
        pourInCup();
    }
    public void boilWater()  //烧水
    {
        System.out.println("将水煮沸");
    }
    public void pourInCup()  
    {
        System.out.println("将饮料调入杯中");
    }
    ////钩子方法:子类选择性覆盖 
    boolean customerWantsCondiments() //顾客是否想要添加东西,因为有的顾客不想添加东西
    {
        return true;
    }
    abstract public void brew();//处理饮料的方式
    abstract public void addCondiments(); //向饮料里加东西
}
class Coffee extends CaffeineBerverage  //咖啡
{
    public void  brew()
    {
        System.out.println("冲泡咖啡");
    }
    public void addCondiments()
    {
        System.out.println("加糖和奶");
    }
    boolean customerWantsCondiments()  //重写
    {
        System.out.println("请问您想要加糖或奶吗? y/n");
        String result=getUserInfo();
        if(result.equals("y"))
        {
            return true;
        }
        else
        {
            return false;
        }

    }
    private String getUserInfo()
    {
        Scanner scanner=new Scanner(System.in);
        String str=scanner.nextLine();
        return str;
    }
}

class Tea extends CaffeineBerverage
{
    public void brew()
    {
        System.out.println("浸泡茶叶");
    }
    public void addCondiments()
    {
        System.out.println("加柠檬");
    }
}

public class Abstract
{
    public static void main(String[] args)
    {
        CaffeineBerverage coffee=new Coffee();
        coffee.prepareRecipe();
        CaffeineBerverage tea=new Tea();
        tea.prepareRecipe();
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sophia__yu/article/details/83245276