day01 【复习回顾、继承、抽象类模板设计模式】

第一章 类和对象

定义类的格式:

修饰符 class 类名{
    // 成员变量(private修饰)
    // 构造方法(空参,满参)
    // set\get方法
    // 成员方法(行为)
}

类使用权限修饰符:public,默认
修饰符:publicprotected,包私有(package-private),private

1.1创建对象的格式

  • 通过调用构造方法创对象:
    类名 对象名 = new 类名(实参);
    类名 对象名 = new 构造器(实参);//类名和构造方法的名字相同

  • 使用对象:符号.(对象名.要什么点什么)
    对象名.成员变量名
    对象名.成员方法名(实参)

  • 3.对象的内存图

在这里插入图片描述

  • 只要是new对象就会在堆区开辟一块独立的空间
  • 只要调用方法,方法就会被加载进栈
  • 只要方法执行完毕,方法就会被弹栈

1.2匿名对象

  • 什么是匿名对象:就是指“没有名字的对象”
有名字的对象:
    Student stu = new Student();
    stu.show();
    stu.study();
匿名对象:
	new Student();
  • 特点:匿名对象只能使用一次

第二章 继承

2.1为什么要有继承

在这里插入图片描述
继承的含义:
继承:在java中指的是“一个类”可以“继承自”“另一个类”。 "被继承的类"叫做: 父类/超类/基类,"继承其他类的类"叫做:子类。继承后,“子类”中就“拥有”了“父类”中所有的成员(成员变量、成员方法)。 “子类就不需要再定义了”。
继承的好处

  1. 提高代码的复用性(减少代码冗余,相同代码重复利用)。
  2. 使类与类之间产生了关系。

2.2继承的格式

通过extends关键字。
Class 父类{…}
Class 子类 extends 父类{…}

需要注意:Java是单继承的,一个类只能继承一个直接父类,并且满足is-a的关系,例如:Dog is a Animal, Student is a Person

人类:
public class Person {
    // 成员变量
    String name;
    int age;
    
    // 功能方法
    public void eat(){
        System.out.println("吃东西...");
    }

    public void sleep(){
        System.out.println("睡觉...");
    }
}
老师类: extends 人类
public class Teacher extends Person {

}
测试:
public class Test {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        System.out.println(t.name);
        System.out.println(t.age);
        t.eat();
        t.sleep();
    }
}
  • 通过继承可以将一些共性的属性,行为抽取到一个父类中,子类只需要继承即可,提供了代码的复用性【共性抽取

2.3继承后成员访问规则【重点】

①构造方法不能被继承

public class Fu{
    public Fu(){
    }
    public Fu(String name,int age){
    }
}
public class Zi extends Fu{
}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi("刘德华", 17);//编译错误,Zi类没有全参构造
    }
}

②父类的“私有成员”可以被子类继承,但子类不能被直接访问。

public class Fu{
    private int num = 100;//私有成员,只能在父类内部使用。
    private void method(){
        System.out.println("私有成员方法");
    }
}
public class Zi extends Fu{

}
public class Demo {
    public static void main(String[] args) {
        Zi z = new Zi();
	    System.out.println(z.num);// 编译错误
        z.method();// 编译错误
    }
}

③当通过“子类”访问非私有成员时,先在子类中找,如果找到就使用子类的,找不到就继续去“父类”中找。

public class Fu{
    int money = 100;
    public void method(){
        System.out.println("Fu 类中的成员方法method");
    }
}
public class Zi extends Fu{
    int money = 1;
     public void method(){
        System.out.println("Zi 类中的成员方法method");
    }
}
public class Demo{
    public static void main(String[] args){
        Zi z = new Zi();
        System.out.println(z.money);//1
        z.method();// Zi 类中的成员方法method
    }
}

2.4方法重写

当父类的逻辑不满足子类使用的时候,可以覆盖重写父类的方法

方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。

public class Fu{
    public void eat(){
        System.out.println("我吃牛肉炖土豆...");
    }
}
public class Zi extends Fu{
	@Override
    public void eat(){//方法重写
        System.out.println("我吃红烧狮子头...");
    }
}
//测试类
public class Demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        zi.eat();// 我吃红烧狮子头...
    }
}

重写的注意事项

  • 方法重写是发生在子父类之间的关系。
  • 子类方法重写父类方法,返回值类型、方法名和参数列表都要一模一样。
  • 子类方法重写父类方法,必须要保证权限大于等于父类权限。
  • 访问权限从大到小: public < protected < (默认) < private
    建议保持一致
  • 使用@Override注解,检验是否重写成功,重写注解校验!
  • 建议重写方法都加上这个注解,一方面可以提高代码的可读性,一方面可以防止重写出错!

2.5this和super关键字

  • this:存储的“当前对象”的引用;
    this可以访问:本类的成员属性、成员方法、构造方法;
  • super:存储的“父类对象”的引用; super可以访问:父类的成员属性、成员方法、构造方法;

this关键字的三种用法

  • this访问本类成员变量: this.成员变量
this访问本类成员变量: this.成员变量
public class Student{
    String name = "张三";
    public void show(){
        String name = "李四";
        System.out.println("name = " + name);// 李四
        System.out.println("name = " + this.name);// 张三
    }
}
  • this访问本类成员方法: this.成员方法名();
public class Student{
    public void show(){
        System.out.println("show方法...");
        this.eat();
    }
    public void eat(){
        System.out.println("eat方法...");
    }
}
  • this访问本类构造方法: this()可以在本类的一个构造方法中,调用另一个构造方法
public class Student{
    public Student(){
        System.out.println("空参构造方法...");
    }

    public Student(String name) {
        this();//当使用this()调用另一个构造方法时,此代码必须是此构造方法的第一句有效代码。
        System.out.println("有参构造方法...");
    }
}
public class Demo {
    public static void main(String[] args) {
        Student stu2 = new Student();
    }
}

super关键字的三种用法

  • super访问父类的成员变量: super.父类成员变量名
public class Fu{
    int money = 100;
}
public class Zi extends Fu{
    int money = 10;
    public void show(){
        int monet = 1;
        System.out.println(“money :+ money);//1
        System.out.println(this.money :+ this.money);//10
        System.out.println(super.money:” + super.money);//100  直接去父类中找
    }
}
  • super访问父类的成员方法: super.成员方法名();
public class Fu{
    public void show(){
        System.out.println("父类的show方法...");
    }
}
public class Zi extends Fu{
   public void show(){
        super.show();
        System.out.println("子类的show方法...");
    }
}
public class Demo {
    public static void main(String[] args) {
       Zi zi = new Zi();
       zi.show();
    }
}
  • super访问父类的构造方法: super()
public class Fu{
    public Fu(){
        System.out.println("Fu 类的空参构造方法..");
    }
    public Fu(String name, int age) {
        System.out.println("Fu 类的有参构造方法..");
    }
}
public class Zi extends Fu{
    public Zi(){
        super();// 调用父类的空参构造方法
        System.out.println("Zi 类的空参构造方法..");
    }
    public Zi(String name,int age){
        super(name,age);// 调用父类的有参构造方法
         System.out.println("Zi 类的有参构造方法..");
    }
}
public class Demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
        System.out.println("----------------------");
        Zi z2 = new Zi("刘德华", 17);
    }
}

注意事项

  1. super访问成员变量和成员方法: 优先去父类中找,如果有就直接使用,如果没有就去爷爷类中找,如果有,就用,依次类推…
  2. 子类的构造方法默认会调用父类的空参构造方法,如果父类中的没有空参构造方法,只定义了有参构造方法,会编译报错

2.6继承内存图原理

在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。

public class Fu {
    int num = 10;
    int numFu = 100;

    public void method(){
        System.out.println("父类中的method方法");
    }
}
public class Zi extends Fu {

    int num = 20;

    public void show(){
        int num = 30;
        System.out.println("访问局部变量num:"+num);
        System.out.println("访问本类成员变量num:"+this.num);
        System.out.println("访问父类成员变量num:"+super.num);
    }

    @Override
    public void method() {
        super.method();
        System.out.println("子类中的method方法");
    }
}
public class ExtendsDemo1 {
    public static void main(String[] args) {
        // 创建一个子类对象
        Zi zi = new Zi();
      请问:内存中存在几个对象?
        1.存在两个,子类对象,父类对象
        2.只存在一个子类的对象【正解】

        // 使用子类对象调用show方法
        zi.show();

        // 使用子类对象调用method方法
        zi.method();
    }
}

在这里插入图片描述
继承的特点:

  • Java只支持单继承,不支持多继承。
  • 一个类只能有一个父类,但是可以有多个子类。
  • 可以多层继承。【有爷爷】

第三章 抽象类的概述和定义

抽象类的概述

  • 概述: 使用abstract关键字修饰的类就是抽象类

  • 特点: 这种类不能被创建对象,它就是用来做父类的,被子类继承的
    抽象类的定义

  • 格式:

修饰符 abstract class 类名{}

  • 例如:

public abstract class Person{}

  • 没有方法体,使用abstract修饰的方法就是抽象方法

public void work(){ //具体方法,具体逻辑 }

修饰符 abstract 返回值类型 方法名(形参列表); 例如: public abstract void work();

注意:如果子类是一个抽象类,父类是抽象类,那么子类可以不用重写父类中的抽象方法
如果子类是一个普通类,父类是抽象类,那么子类必须重写父类中所有的抽象方法

3.1模板设计模式

设计模式概述

  • 设计模式就是解决一些问题时的固定思路,也就是代码设计思路经验的总结。
    特定的解决问题的方案,最佳实践

模板设计模式概述

  • 针对某些情况,在父类中指定一个模板,然后根据具体情况,在子类中灵活的具体实现该模板
  • 抽象类体现的就是模板思想,模板是将通用的东西在抽象类中具体的实现,而模板中不能决定的东西定义成抽象方法,让使用模板(继承抽象类的类)的类去重写抽象方法实现需求
  • 抽象类: — 看成是模板
  • 模板是将通用的东西在抽象类中具体的实现 : 非抽象方法定义一些通用的功能
  • 模板中不能决定的东西定义成抽象方法

模板模式的实现步骤

  • 定义父类(抽象类)作为模板
  • 在父类中定义"模板方法"— 实现方法(模板)+抽象方法(填充模板)
  • 子类继承父类,重写抽象方法(填充父类的模板)
  • 测试类:
    • 创建子类对象,通过子类调用父类的“实现的方法”+ “子类重写后的方法” e

案例演示
假如我现在需要定义新司机和老司机类,新司机和老司机都有开车功能,开车的步骤都一样,只是驾驶时的姿势有点不同,新司机:开门,点火,双手紧握方向盘,刹车,熄火,老司机:开门,点火,右手握方向盘左手抽烟,刹车,熄火。那么这个时候我们就可以将固定流程写到父类中,不同的地方就定义成抽象方法,让不同的子类去重写

分析:

  • 定义司机抽象类,作为模板
    • 开车功能(非抽象方法): 开车的步骤一样的
      • 开门
      • 点火
      • 开车姿势
      • 刹车
      • 熄火
    • 开车姿势功能(抽象方法): 供子类重写
  • 新司机类 继承司机类
  • 老司机类 继承司机类
// 司机开车的模板类
public abstract class Driver {
    public void go() {
        System.out.println("开门");
        System.out.println("点火");
        // 开车姿势不确定?定义为抽象方法
        ziShi();
        System.out.println("刹车");
        System.out.println("熄火");
    }

    public abstract void ziShi();
}
司机模板
public class NewDriver extends Driver {

    @Override
    public void ziShi() {
        System.out.println("新司机双手紧握方向盘");
    }
}

public class OldDriver extends Driver {
    @Override
    public void ziShi() {
        System.out.println("老司机右手握方向盘左手抽烟...");
    }
}
测试类
public class Demo02 {
    public static void main(String[] args) {
        NewDriver nd = new NewDriver();
        nd.go();

        OldDriver od = new OldDriver();
        od.go();
    }
}

可以看出,模板模式的优势是,模板已经定义了通用架构,使用者只需要关心自己需要实现的功能即可!非常的强大!

抽象类存在的意义是为了被子类继承,否则抽象类将毫无意义,抽象类体现的是模板思想,模板是将通用的东西在抽象类中具体的实现,而模板中不能决定的东西定义成抽象方法,让使用模板(继承抽象类的类)的类去重写抽象方法实现需求,这是典型的模板思想。

发布了3 篇原创文章 · 获赞 0 · 访问量 19

猜你喜欢

转载自blog.csdn.net/m0_46690280/article/details/105544282