01-JavaSE【封装、继承、抽象】

文章目录

      • 一、面向对象回顾
        • 学习目标
        • 内容讲解
        • 【1】类的定义格式
        • 【2】创建对象
        • 内容小结
      • 二、 面向对象特性之【封装】
        • 学习目标
        • 内容讲解
        • 【1】private关键字
        • 【2】封装的操作步骤
        • 内容小结
      • 三、 构造器(Constructor)
        • 学习目标
        • 内容讲解
        • 【1】构造器的定义及其作用
        • 【2】代码演示
        • 内容小结
      • 四、this关键字
        • 学习目标
        • 内容讲解
        • 【1】this的含义
        • 【2】作用
        • 【3】代码演示
        • 内容小结
      • 五、 匿名对象
        • 学习目标
        • 内容讲解
        • 【1】什么是匿名对象
        • 【2】匿名对象怎么用
        • 【3】代码演示
        • 内容小结
      • 六、 面向对象特性之【 继承】
        • 学习目标
        • 内容讲解
        • 【1】继承的概述
        • 【2】继承的格式
        • 内容小结
        • 01、继承入门案例
        • 学习目标
        • 内容讲解
        • 【需求】
        • 【分析】
        • 【步骤】
        • 【代码】
        • 内容小结
        • 02、 继承中成员变量的使用特点
        • 学习目标
        • 内容讲解
        • 【1】继承中成员变量的使用特点
        • 【2】继承中子类方法中局部变量,子类成员变量中,父类成员变量中名字冲突
        • 内容小结
        • 03、 继承中成员方法的使用特点
        • 学习目标
        • 内容讲解
        • 【1】方法的访问特点
        • 【2】代码示例
        • 内容小结
        • 04、方法重写
        • 学习目标
        • 内容讲解
        • 【1】重写概念
        • 【2】注解
        • 【3】注意事项
        • 内容小结
        • 05、继承中构造方法的使用特点
        • 学习目标
        • 内容讲解
        • 内容小结
        • 06、继承的特点
        • 学习目标
        • 内容讲解
        • 内容小结
      • 七、super和this关键字使用小结
        • 学习目标
        • 内容讲解
        • 【1】super和this的异同
        • 【2】this调用本类构造方法
        • 内容小结
      • 八、抽象
        • 01、抽象类的定义
        • 学习目标
        • 内容讲解
        • 【定义】
        • 【格式】
        • 【使用场景】
        • 【代码实践】
        • 内容小结
        • 02、抽象类的使用
        • 学习目标
        • 内容讲解
        • 【1】抽象类的使用方式
        • 【2】代码实践
        • 内容小结
        • 03、抽象类的使用注意事项
        • 学习目标
        • 内容讲解
        • 04 、抽象类存在的意义
        • 学习目标
        • 内容讲解
        • 内容小结
      • 九、模板设计模式
        • 学习目标
        • 内容讲解
        • 内容小结
      • 十、总结
        • 内容小结

一、面向对象回顾

学习目标

能够定义类并创建对象

内容讲解
【1】类的定义格式

关键字:class

修饰符 class 类名{
  成员变量
  成员方法
  构造方法
  代码块
  内部类
}

例如:

定义一个学生类,包含属性姓名,年龄

public class Student{
   public  String name;
   public  int age;
}

默认有一个无参构造方法

【2】创建对象

关键字:new

类名 对象名  = new 类名(参数);

例如:

创建学生对象

Student stu = new Student();
//给姓名赋值为小明
stu.name = "小明";
stu.age = 18;

System.out.println(stu.name);
内容小结

类定义的关键字:class

对象定义的关键字:new

二、 面向对象特性之【封装】

学习目标
  • 理解关键字private
  • 能够使用private对类中成员进行封装
内容讲解
【1】private关键字

private关键字的含义就是私有。可以用来对成员进行封装

【2】封装的操作步骤
  • 第一步:先把成变量使用private封装

  • 第二步:提供getter、setter方法

举例:

定义一个学生类,含有属性姓名,年龄。对姓名和年龄进行封装,并提供可访问的getter、setter方法

public class Demo01 {
    public static void main(String[] args) {
        Student stu = new Student();
        //给name属性赋值小明
        //stu.name
        stu.setName("小明");

        //System.out.println(stu.name);
        System.out.println(stu.getName());

    }
}

/*
定义一个学生类,含有属性姓名,年龄。对姓名和年龄进行封装,并提供可访问的getter、setter方法
 */
class Student{
    //1. 将成员变量使用private进行修饰
    private String name;
    private int age;

    //2. 提供getter、setter方法
    //name的getter和setter方法
    //getter:获取成员变量值
    public String getName() {
        return name;
    }

    //setter:负责赋值
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
内容小结

封装使用什么关键字?

private

封装的步骤?

第一步:先把成变量使用private封装
第二步:提供getter、setter方法

三、 构造器(Constructor)

学习目标
  • 能够定义并使用类的构造器
内容讲解
【1】构造器的定义及其作用

格式:

修饰符 类名 (形参){
   给成员变量初始化值
}

特点:

  1. 没有返回值(即使void也不用写)
  2. 方法名一定是和当前类的类名一样
  3. 构造方法支持重载(同名不同参)

作用:

  • 结合关键字new创建对象,也可以同时给成员变量赋值。
【2】代码演示

定义一个学生类,含有属性姓名,年龄。对姓名和年龄进行封装,并提供可访问的getter、setter方法

同时提供无参构造方法,满参构造方法。

public class Demo01 {
    public static void main(String[] args) {
        //使用无参构造方法创建对象
        Student stu = new Student();
        stu.setName("昌老师");
        stu.setAge(18);
        System.out.println(stu.getName() + "::" + stu.getAge());
        stu.study();

        //使用满参构造方法创建对象
        Student stu2 = new Student("苏群", 17);
        System.out.println(stu2.getName() + "::" + stu2.getAge());
        stu2.study();



    }
}

//定义一个学生类,含有属性姓名,年龄。对姓名和年龄进行封装,并提供可访问的getter、setter方法
//同时提供无参构造方法,满参构造方法。

class Student {
    //1.成员变量
    private String name;
    private int age;

    //2.构造方法
    // 无参构造方法,(如果写了其他非无参构造方法,就没有默认的无参了)
    public Student() {
    }

    // 满参构造方法

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }


    //3.getter/setter

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    //4.行为方法
    public void study() {
        System.out.println(name + "正在认真的学习Java");
    }
}

内容小结

构造方法特点?

  • 没有返回值
  • 可以重载
  • 方法名和类名一样

构造方法有什么作用?

  • 为了结合new关键字创建对象,可以给成员变量初始化值

四、this关键字

学习目标
  • 理解this关键字的含义
  • 能够使用this关键字解决局部变量和成员变量冲突问题
内容讲解
【1】this的含义
  • this就是指当前类型的对象
  • this一般出现在构造器,实例方法中
    • 如果在构造器中,this就是当前new的对象。
    • 如果出现在实例方法,this就是调用该方法的对象。
【2】作用

this关键字就是为了解决局部变量和成员变量名字冲突的调用问题。

格式:

this.成员变量

例如:

//构造方法
public Student(String name,int age){
  this.name=name;
  this.age = age;
}


//setter
public void setName(String name){
  this.name = name;
}
【3】代码演示
public class Demo01 {
    public static void main(String[] args) {
        Student stu = new Student("张三");
        System.out.println("stu.name = " + stu.name);

        System.out.println("stu=" + stu);//stu=_03this关键字.Student@6bf256fa


    }
}

class Student {
    public String name;

    public Student(String name) {
        //name = name;//没有设置成功,使用冲突的局部变量和成员变量,就近选择局部变量
        this.name = name;
        System.out.println("this=" + this);//this=_03this关键字.Student@6bf256fa
    }

    //实例方法自己验证:调用方法的对象就是方法内部的this对象
}
内容小结
  • this关键字含义?

    this在构造器中就是指当前创建的对象,如果在实例方法中就是调用方法的对象

  • this关键字有什么作用?

    区分名字冲突的成员变量和局部变量。

五、 匿名对象

学习目标
  • 能够定义类的匿名对象
内容讲解
【1】什么是匿名对象
  • 有名对象:有对象名保存地址的对象

    Student stu = new Student();
    
    Scanner sc = new Scanner(System.in);
    
  • 匿名对象:没有对象名的对象就是匿名对象

    new Student();
    
    new Scanner(System.in);
    
【2】匿名对象怎么用

匿名对象的使用特点:只能使用一次,对象名可以怎么用,匿名对象也可以怎么用。

  • 直接使用匿名对象调用方法
  • 直接当做一个参数传给方法
  • 直接当做返回值进行传递
【3】代码演示
public class Demo01 {
    public static void main(String[] args) {
        //- 直接使用匿名对象调用方法
        new Student().setName("张三");

        new Student("少林").study();


        //- 直接当做一个参数传给方法
        showStudent(new Student("李四"));

        //有名对象
        Student stu = new Student("张三");
        showStudent(stu);




    }

    public static void showStudent(Student stu) {
        stu.study();
    }


    //- 直接当做返回值进行传递
    public static Student getStudent() {
        return new Student("王五");
    }


}

class Student{
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("调用了set方法");
        this.name = name;
    }

    public void study() {
        System.out.println(name+"正在认真的学习Java");
    }
}

内容小结
  • 什么是匿名对象?

    没有对象名的对象

  • 匿名对象怎么用?

    只能用一次,对象名可以怎么用,匿名对象也可以怎么用

    • 直接调用成员
    • 直接当做方法参数传递
    • 直接当做返回值传递

六、 面向对象特性之【 继承】

学习目标
  • 理解继承的思想

  • 能够使用关键字extends书写继承的代码

  • 能够知道继承的好处

内容讲解
【1】继承的概述

面向对象的特性:封装,继承,多态

设计类的过程中就可以去使用继承,可以提高代码的复用性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbUtVkOc-1616501047834)(imgs/image-20201028103456573.png)]

【2】继承的格式

Java中如何完成类型的继承:需要借助关键字,extends,implements

今日讲extends,类继承类使用 extends。

class Fu {  //父类,基类,超类
  成员
}


class Zi extends Fu{  // 子类
  
}

表示Zi类继承了Fu类。
内容小结
  • 继承的思想?

    比如A类继承了B类,A就可以拥有B中的属性成分。

  • 继承的好处?

    提高代码的复用性

  • 继承使用的关键字?

    extends

  • 格式

    class A{}
    class B{}
    
    A继承B
    class A extends B{}
    
01、继承入门案例
学习目标
  • 能够使用继承思想定义类
内容讲解
【需求】

以继承的思想定义以下类型:

  1. 学生类
    属性:姓名,年龄
    行为:吃饭,睡觉
  2. 老师类
    属性:姓名,年龄,薪水
    行为:吃饭,睡觉,教书
  3. 班主任
    属性:姓名,年龄,薪水
    行为:吃饭,睡觉,管理
【分析】

如果不用继承的思想定义类,发现有属性:姓名,年龄。行为:吃饭,睡觉,会重复定义。

使用继承的思想定义类:

  • 把共性的属性或者行为抽取到父类中。
  • 定义子类继承父类。重复的部分不用定义,特有的需要定义。
【步骤】
  1. 抽取父类,人(属性:姓名,年龄 行为:吃饭,睡觉)
  2. 然后再定义子类
  3. 测试
【代码】
public class Demo01 {
    public static void main(String[] args) {
        //3. 测试
        //学生类:
        Student stu = new Student();
        stu.name = "张三";//name就是父类继承下来的

        stu.eat();//来自父类的方法
        stu.sleep();//来自父类的方法


        //老师类:
        Teacher t = new Teacher();
        t.name = "昌老师";//来自父类的属性
        t.salary = 100000;//来自本类

        t.eat();//来自父类的方法
        t.teaching();//来自本类的方法


    }
}

//1. 抽取父类,人(属性:姓名,年龄  行为:吃饭,睡觉)
class Person {   //父类
    public String name;
    public int age;

    public void eat() {
        System.out.println(name + "在吃饭饭!");
    }

    public void sleep() {
        System.out.println(name + "在睡觉觉!");
    }
}

//2. 然后再定义子类
class Student extends Person {

}


class Teacher extends Person {
    //特有的属性
    public int salary;//薪资

    //特有的行为
    public void teaching() {
        System.out.println(name + "老师,在教书书!");
    }
}

内容小结

如何使用继承思想设计类?

在设计很多类的时候,可以将共性的属性或者行为抽取到父类中。

02、 继承中成员变量的使用特点
学习目标
  • 理解继承中子类访问父类成员变量的特点
  • 能够解决方法中变量,成员变量中及其父类中成员变量冲突
内容讲解
【1】继承中成员变量的使用特点
  • 子类可以直接使用父类中非私有的属性
    • 如果子类和父类相同包,可以直接使用父类的public,protected,package-private修饰的属性
    • 如果子类和父类在不同包,可以直接使用父类的public,protected修饰的属性。
  • 如果是私有的,也可以使用getter,setter去进行访问
  • 如果子类中存在与父类相同的成员变量,就近先使用子类的(会把父类同名成员变量隐藏)。

【代码测试】

class Fu{
    public int age;  //公共的
    protected int height; //受保护的
    int weight;// 包私有的
    private String sex; //私有的


    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

class Zi extends Fu{
    public void show1() {
        System.out.println(age);
        System.out.println(height);
        System.out.println(weight);
        //System.out.println(sex);//不能访问父类私有成分
        System.out.println(getSex());//可以借助getter、setter方法进行访问
    }
}
【2】继承中子类方法中局部变量,子类成员变量中,父类成员变量中名字冲突

在子类方法中访问:

位置 子类方法中局部变量 子类成员变量 父类成员变量
访问 直接访问 this.成员变量 super.成员变量

代码示例:

public class Demo02 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.show();

    }
}

class Animal{
    int age = 10;
}

class Cat extends Animal{
    int age = 20;

    public void show() {
        int age = 30;
        //要求,把所有age变量的值都打印出来
        System.out.println(age);//30
        System.out.println(this.age);//20
        System.out.println(super.age); // 10
    }

}
内容小结

继承中子类访问父类成员变量的特点?

  • 同包中:公共的,受保护的,包私有修饰的属性是可以直接访问,私有不行
  • 不同包:公共的,受保护的修饰的属性是可以直接访问

不能直接访问的成分,可以借助公共的getter,setter方法进行访问

如果方法中局部变量,本类成员变量,父类的成员变量名字有冲突?

局部变量:直接访问

本类成员变量:this.

父类成员变量:super.

03、 继承中成员方法的使用特点
学习目标
  • 理解继承中子类访问父类成员方法的特点
内容讲解
【1】方法的访问特点

访问特点和成员变量是一样的。

同包中:子类可以访问父类的public,protected,包私有修饰的方法

不同包:子类可以访问父类的public,protected,的方法

如果子类中定义声明了与父类一样的方法,优先访问子类的方法。

【2】代码示例
public class Demo01 {
    public static void main(String[] args) {
        //创建子类对象访问方法

        Zi zi = new Zi();
        zi.test1();
        zi.test2();
        zi.test3();
        //zi.test4(); //同包中,私有的父类方法不能访问

        //父类和子类方法相同
        zi.test5();

    }
}


class Fu {
    public void test1() {
        System.out.println("这是父类的public修饰的test1方法");
    }


    protected void test2() {
        System.out.println("这是父类的protected修饰的test2方法");
    }

    void test3() {
        System.out.println("这是父类的包私有修饰的test3方法");
    }

    private void test4() {
        System.out.println("这是父类的private修饰的test4方法");
    }

    public void test5() {
        System.out.println("来自父类的方法");
    }

}

class Zi extends Fu {

    public void test5() {
        System.out.println("来自子类的方法");
    }

}
内容小结

继承中子类访问父类方法的特点?

同包中:public,protected,包私有修饰的成分可以访问

不同包:public,protected修饰的成分可以访问

继承中如果子类方法和父类方法相同了,子类对象调用该方法优先访问谁呢?

优先访问子类方法

04、方法重写
学习目标
  • 能够理解为什么要重写
  • 能够覆盖重写父类方法
内容讲解
【1】重写概念

当父类中方法继承到子类后,不满足子类需要的时候,子类就可以对这个方法进行覆盖,重写(Override)。

如何重写父类中的方法呢?

声明不变,重新实现。

  • 方法的声明:修饰符 返回值类型 方法名 (参数列表)
  • 逻辑的重新实现:方法体的逻辑重写
修饰符 返回值类型 方法名 (参数列表){
  方法体的逻辑重写
}

例如:

class Animal {
  public void eat(){
    System.out.println("吃东西");
  }
}


class Cat extends Animal{
  //重写eat方法
  public void eat(){
    System.out.println("猫吃鱼");
  }
}

【2】注解

@Override :注解,表示该方法是重写的方法。

IDEA重写方法:

  1. 直接写方法名,回车补全
  2. 快捷键:Ctrl+O

代码实例


public class Demo01 {
    public static void main(String[] args) {
        Cat c = new Cat();
        c.eat();

    }
}


class Animal {
    public void eat() {
        System.out.println("动物吃东西!");
    }

    public void sleep() {

    }
}

class Cat extends Animal {
    //直接写方法名,回车补全
  /*  @Override //注解:表示该方法是重写的方法
    public void eat() {
        super.eat();//调用父类的eat方法

        System.out.println("猫吃鱼!!");
    }*/


  //Ctrl+O:快捷重写
    @Override
    public void eat() {
        System.out.println("猫吃鱼!!");
    }

    @Override
    public void sleep() {
        super.sleep();
    }
}

【3】注意事项
  1. 方法重写是发生在子父类之间的关系。

  2. 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。

  3. 子类方法覆盖父类方法,返回值类型、函数名和参数列表都要一模一样。
    返回值类型(子类返回值类型要小于等于父类返回值类型【不考虑基本数据类型】)

    子类继承父类,子类范围更具体更小的,父类范围会更抽象更宽泛。父类型大于子类型。

平时重写方法时:声明不变

内容小结

为什么要重写?

父类继承到子类的方法逻辑不满足子类需要时,子类可以进行重写。

如何重写?

声明不变,重新实现。

05、继承中构造方法的使用特点
学习目标
  • 能够使用super调用父类构造方法初始父类属性
内容讲解

构造方法是不能冲父类继承到子类中的,但是可以在子类中借助super关键字进行访问。

如何借助super关键字调用父类的构造方法?

  • 格式:

    需要在子类构造方法中第一句位置,使用super调用

    super() 调用父类的无参构造
    super(参数) 调用父类的有参构造方法
    
  • 特点:

    super调用构造方法一次只能有一个。

    父类的构造方法,总是在子类构造方法执行前,执行。

    子类的构造方法,一定会先调用父类构造方法,如果没有显式使用super调用,默认会有super()

代码实践

public class Demo01 {
    public static void main(String[] args) {
        Student stu = new Student();
        System.out.println("stu.name = " + stu.name);

        //使用满参构造方法创建对象
        Student stu2 = new Student("李四",20,1);
        System.out.println("stu2.name = " + stu2.name);
        System.out.println("stu2.age = " + stu2.age);
        System.out.println("stu2.id = " + stu2.id);
    }
}

class Person {
    public String name;
    public int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Student extends Person {
    public int id;

    public Student() {
        //super();//如果没有写,默认会有
        super("张三", 18);
    }

    //构建一个满参,包含本类的属性,父类的属性初始化
    public Student(String name, int age,int id) {
        super(name, age);
        this.id=id;
    }

}

内容小结

如何调用父类的构造方法?

  1. 使用关键字:super
  2. 位置要求:必须在子类构造方法的第一句
  3. 格式:super(参数)
06、继承的特点
学习目标
  • 能够理解继承的三个特点
内容讲解

继承的特点有三个:

  1. 只支持单继承

    class A {}
    class B {}
    class C extends A{}
    class D extends A,B{} //不行,错误
    
  2. 允许一个父类有多个子类

    class A{}
    class B extends A{}
    class C extends A{}
    
  3. 允许类多层继承

    class A{}  //如果一个类没有显式的继承一个类,默认会继承Object(上帝类)
    class B extends A{}
    class C extends B{}
    class D extends C{}
    

    继承也是具有传递性的,A中的成分不仅会继承给B,也会继承给C,也会继承给D。

内容小结

继承三个特点?

  • 单继承
  • 一个父类可有多个子类
  • 可以多层继承

七、super和this关键字使用小结

学习目标
  • 能够区分super和this的用法
  • 能够使用this关键字调用本类中的构造方法
内容讲解
【1】super和this的异同

super和this都是指代的同一个对象,this表示的本类空间,super表示的父类空间。

this和super用法一样:

  • 调用成员变量
  • 调用成员方法
  • 调用构造方法

区别在于,this调用的是本类的成分,super调用父类的成分。

【2】this调用本类构造方法
  • 格式:

    位置:必须在本类构造方法的第一句

    this(参数) 
    

    注意:不能调用自身构造方法

  • 特点:

    1. this和super调用构造方法不能共存的

代码实践:

public class Demo01 {
    public static void main(String[] args) {
        //使用无参构造方法创建对象,name和age都有初始的值

        Student stu = new Student();
        System.out.println("stu.name = " + stu.name);
        System.out.println("stu.age = " + stu.age);

    }
}

class Student {
    public String name;
    public int age;

    public Student() {
        //name : 尼古拉斯.赵四
        //age : 18
        //name = "尼古拉斯.赵四";
        //age = 18;
        this("尼古拉斯.赵四", 18);
    }

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }


}

内容小结

super和this是的是什么?

只同一个对象的两个空间,super指父类空间,this指本类空间。

this如何调用本类其他构造方法?

位置:在本类的构造方法第一句

格式:this(参数)

不能调用自身,否则会报错。

this为何要调用本类其他构造方法?

  • 为了初始化成员
  • 提高代码的复用性

八、抽象

01、抽象类的定义
学习目标
  • 理解什么是抽象类,抽象方法
  • 能够定义抽象类和抽象方法
内容讲解
【定义】

abstract关键字:表示抽象。

使用关键字abstract修饰的类,称为抽象类。

使用关键字abstract修饰的方法,没有方法体,且以分号结尾的方法,称为抽象方法。

【格式】
//抽象类
修饰符 abstract class 类名{
  //抽象方法
  修饰符 abstract 返回值类型 方法名(参数列表);
}
  • 在抽象类中,可以没有抽象方法。但是如果一个类中存在抽象方法,该类一定是抽象类。
  • 抽象类本质上也是一个类,也可以有普通类中的各种成分(成员变量,成员方法,构造方法)
【使用场景】

抽象类,抽象方法的使用场景。

抽取多个类的父类时,通常就会使用抽象类。如果多个类中有共同的方法,但是逻辑具体由不同,此时就可以使用抽象方法。

抽象类就是以父类的角色存在。

【代码实践】

学生:姓名,年龄,吃饭,工作

老师:姓名,年龄,吃饭,工作

班主任:姓名,年龄,吃饭,工作

抽取父类人,描述上面的共同的父类。

分析:

属性:姓名,年龄

行为:吃饭,工作,吃饭大家都一样的,可以使用具体的方法,而工作,因为每个角色的内容不同,可以使用抽象方法。

public abstract class Person {
    //属性
    public String name;
    public int age;

    //构造方法


    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }


    //行为
    public void eat() {
        System.out.println("吃饭");
    }

    //抽象方法
    public abstract void work();
}
内容小结

什么叫抽象类,什么叫抽象方法?

被abstract修饰的类就是抽象类,被abstract修饰的方法就是抽象方法

抽象的关键字是什么?

abstract

什么时候可以使用抽象类,抽象方法?

抽取多个类的父类时,通常就会使用抽象类。如果多个类中有共同的方法,但是逻辑具体由不同,此时就可以使用抽象方法。

02、抽象类的使用
学习目标
  • 能够使用抽象抽象
内容讲解
【1】抽象类的使用方式
  1. 抽象类不能直接实例化对象使用。

  2. 可以定义子类继承抽象的父类,如果存在抽象方法,要将所有的抽象方法进行重写

    重写抽象方法可以叫做实现。

  3. 如果子类不重写抽象方法,你可将子类也变成抽象类。

【2】代码实践

使用上一个知识点的Person抽象类作为父类定义学生类,老师类。

当我们使用一个类继承一个抽象类时,发现报错:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lIucYJa0-1616501047838)(imgs/image-20201028160114179.png)]

类Student必须要么定义成抽象类,要么把来自父类的抽象方法work实现
public class Demo01 {
    public static void main(String[] args) {
        //抽象类不能创建对象
        //Person p1 = new Person();

        //使用时,用其子类即可
        Student stu = new Student();
        stu.work();
        stu.sleep();
    }
}

//创建子类去继承抽象类,并实现抽象方法

class Student extends Person{

    @Override
    public void work() {
        System.out.println("学生的工作,就是学习!!");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉站着睡觉");
    }
}

abstract class Teacher extends Person {
    //父类的抽象方法就会继承到子类Teacher中。
}
内容小结

抽象类怎么使用?

  • 不能创建对象
  • 可以使用子类继承抽象类,实现所有的抽象方法。
  • 如果子类不实现抽象方法,子类要定义成为抽象类
03、抽象类的使用注意事项
学习目标
内容讲解
  1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。

    理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。

  2. 抽象类中,可以有构造器,是供子类创建对象时,初始化父类成员使用的。

    理解:子类的构造方法中,有默认的super(),需要访问父类构造方法。

  3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。

    理解:未包含抽象方法的抽象类,目的就是不想让调用者创建该类对象,通常用于某些特殊的类结构设计。

  4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则子类也必须定义成抽象类,编译无法通过而报错。

    理解:假设不重写所有抽象方法,则类中可能包含抽象方法。那么创建对象后,调用抽象的方法,没有意义。

04 、抽象类存在的意义
学习目标
  • 能够理解抽象类存在的意义
内容讲解

抽象类在抽取父类型的时候可以使用,有一些方法假如具体子类型有不同的逻辑,可以使用抽象方法。

抽象类的子类必须要实现所有的抽象方法。否则要变成抽象类。

对子类有一个约束,子类会根据父类而进行设计,体现一种模板思想。

内容小结

抽象类可以当做父类型,里面定义抽象方法,可以约束子类一定要做一个具体的实现。

九、模板设计模式

学习目标
  • 理解什么是设计模式
  • 能够使用抽象类设计模板模式
内容讲解

什么是设计模式?

设计模式体现的是解决一个问题一个需求的一种最佳实践。

模板设计模式:

可以利用抽象类定义一些需要子类完成的一系列功能的模板方法。子类继承抽象类之后,只要实现抽象方法。

而模板方法直接继承到子类,不需要重写。子类调用模板方法的时候,就可以按照模板的逻辑进行执行了。

例如:

我现在需要定义新司机和老司机类,新司机和老司机都有开车功能,开车的步骤都一样,只是驾驶时的姿势有点不同,

新司机:开门,点火,双手紧握方向盘,刹车,熄火老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火

使用模板设计模式进行定义相关的类,步骤:

  1. 抽取所有的共性方法到抽象类中,如果具体类型的逻辑不同的使用抽象方法定义。
  2. 定义模板方法,定义每个子类都必须遵循的一个业务逻辑(流程)。

抽象父类(模板)


//新司机:开门,点火,双手紧握方向盘,刹车,熄火,老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火。
abstract class Driver {

    //定义方法
    public void open() {
        System.out.println("开门");
    }

    public void start() {
        System.out.println("开火启动");
    }

    public abstract void zishi();

    public void breakDown() {
        System.out.println("刹车");
    }

    public void stop() {
        System.out.println("熄火");
    }

    //模板方法:定义流程
    public final void drive() {//final加上的目的就是为了阻断重写
        open();
        start();
        zishi();
        breakDown();
        stop();
    }

}


测试类及其子类:


public class Demo01 {
    public static void main(String[] args) {
        NewDriver d1 = new NewDriver();
        d1.drive();//调用模板方法

        System.out.println("=============");


        OldDriver oldDriver = new OldDriver();
        oldDriver.drive();//调用模板方法
    }
}

class OldDriver extends Driver {

    @Override
    public void zishi() {
        System.out.println("左手抽烟,右手搭在方向盘");
    }
}

class NewDriver extends Driver {

    @Override
    public void zishi() {
        System.out.println("双手握紧方向盘,聚精会神");
    }


}
内容小结

什么时候使用模板设计模式?

当子类都有一个固定的业务流程时,就可以使用模板设计模式

如何设计?

  1. 抽取所有的共性方法到抽象类中,如果具体类型的逻辑不同的使用抽象方法定义。
  2. 定义模板方法,定义每个子类都必须遵循的一个业务逻辑(流程)。

十、总结

  • 能够写出类的继承格式

    使用extends关键字。

    class A{}
    class B extends A{}
    
  • 能够说出类继承的三个特点

    单继承
    一个父类可以有多个子类
    可以多层继承,有传递性
    
  • 能够说出继承中子类访问成员的特点

    子类和父类在同包:被public,protected,包私有修饰的的成员,子类可以访问

    子类和父类在不同包::被public,protected 修饰的的成员,子类可以访问

    如果子类定义了与父类一样的成员,优先访问子类的。

  • 能够说出继承中方法重写的使用场景

    当父类的方法继承到子类其逻辑不能满足子类需要时,就可以进行重写

  • 能够说出this和super的使用方式及其区别

    使用方式:

    • 可以访问成员变量,成员方法,构造方法

    区别:

    this访问本类,super访问父类

  • 能够定义抽象类和抽象方法

    abstract:表示抽象

    abstract class 类名{
     public	abstract void test();
    }
    
  • 能够使用含有抽象方法的抽象类

    • 子类要实现所有的抽象方法
    • 将子类变成抽象类
    • 抽象类不能实例化对象
  • 能够说出父类抽象方法的存在意义

System.out.println(“熄火”);
}

//模板方法:定义流程
public final void drive() {//final加上的目的就是为了阻断重写
    open();
    start();
    zishi();
    breakDown();
    stop();
}

}


测试类及其子类:

```java

public class Demo01 {
    public static void main(String[] args) {
        NewDriver d1 = new NewDriver();
        d1.drive();//调用模板方法

        System.out.println("=============");


        OldDriver oldDriver = new OldDriver();
        oldDriver.drive();//调用模板方法
    }
}

class OldDriver extends Driver {

    @Override
    public void zishi() {
        System.out.println("左手抽烟,右手搭在方向盘");
    }
}

class NewDriver extends Driver {

    @Override
    public void zishi() {
        System.out.println("双手握紧方向盘,聚精会神");
    }


}
内容小结

什么时候使用模板设计模式?

当子类都有一个固定的业务流程时,就可以使用模板设计模式

如何设计?

  1. 抽取所有的共性方法到抽象类中,如果具体类型的逻辑不同的使用抽象方法定义。
  2. 定义模板方法,定义每个子类都必须遵循的一个业务逻辑(流程)。

你可能感兴趣的:(玩转Java,java,封装,面向对象编程,抽象类,编程语言)