java学习笔记 - 第十章:面向对象编程(高级部分)

第十章:面向对象编程(高级部分)

  • 总体内容
  • 类变量
    • 类变量的引出
    • 类变量快速入门(静态变量)
    • 类变量的内存布局
    • 类变量的定义和访问
    • 类变量使用细节
  • 类方法
    • 类方法快速入门
    • 类方法最佳实现
    • 类方法注意事项和细节
    • 类成员小练习
  • 理解main方法语法
    • main语法说明
    • main特别说明
    • main动态传值(在idea中传参)
  • 代码块
    • 基本介绍及语法
    • 代码块的好处及快速入门例子
    • 代码块使用细节
    • 代码块小练习
  • 单例设计模式
    • 设计模式的介绍
    • 单例模式的介绍
    • 单例模式饿汉式
    • 单例模式懒汉式
    • 饿汉和懒汉的小结和区别
  • final关键字
    • final基本介绍
    • final注意事项和细节
    • final小练习
  • 抽象类
    • 引出抽象类
    • 抽象类快速入门
    • 抽象类的介绍
    • 抽象类的细节
    • 抽象类小练习(易)
    • 模板设计模式--> 抽象类最佳实践
      • 模板设计模式引出及步骤
      • 引申 for循环 快捷模板:
      • 引申:获取当前时间
  • 接口
    • 接口快速入门
    • 接口基本介绍
    • 接口的应用场景
    • 接口使用细节
    • 接口的小练习1
    • 接口vs继承
    • 接口多态特性
    • 接口的小练习2
  • 类定义的进一步完善
  • 四种内部类
    • 基本介绍
    • 四种内部类
    • 局部内部类
    • 匿名内部类(重要!!!)
      • 匿名内部类的本质(基于接口)
      • 匿名内部类的使用(普通类、抽象类)
      • 匿名内部类的细节
      • 匿名内部类的最佳实践
      • 小练习
    • 成员内部类
    • 静态内部类
  • 本章作业
    • 作业1(static)
    • 作业2(题意->代码(静态属性))
    • 作业3(匿名内部类作为参数)
    • 作业4(局部内部类的使用)
    • 作业5(工厂类)
    • 作业6(成员内部类)

总体内容

java学习笔记 - 第十章:面向对象编程(高级部分)_第1张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第2张图片

类变量

类变量的引出

  1. 提出问题
    java学习笔记 - 第十章:面向对象编程(高级部分)_第3张图片
  2. 用现有方法解决 的思路和分析
    java学习笔记 - 第十章:面向对象编程(高级部分)_第4张图片
  3. 正式引出类变量(静态变量)
    类变量是属于类的,所以可以被类的所有对象共享
    java学习笔记 - 第十章:面向对象编程(高级部分)_第5张图片

类变量快速入门(静态变量)

  1. 在类中定义一个类变量(加上static)
    java学习笔记 - 第十章:面向对象编程(高级部分)_第6张图片
  2. 使用类的不同对象去引用(访问的是同一个变量)
    java学习笔记 - 第十章:面向对象编程(高级部分)_第7张图片
  3. 也可用类名访问类变量
    java学习笔记 - 第十章:面向对象编程(高级部分)_第8张图片
  4. 简略内存图
    java学习笔记 - 第十章:面向对象编程(高级部分)_第9张图片

类变量的内存布局

  1. 在jdk8以前,类变量在方法区的静态域中
  2. 在jdk8以后,类变量在堆的class对象中
  3. 不管类变量在哪,共识是:
    3.1. 类变量被同一个类的所有对象所共享(不同存储地方不影响对它的使用)
    3.2. 类变量在类加载时就生成了
    3.3 类变量是随着类加载而创建,所以即使没有创建对象实例也能访问

java学习笔记 - 第十章:面向对象编程(高级部分)_第10张图片

类变量的定义和访问

  1. 什么是类变量
    在这里插入图片描述
  2. 定义类变量的语法
    java学习笔记 - 第十章:面向对象编程(高级部分)_第11张图片
  3. 访问类变量
    3.1 类变量是随着类加载而创建,所以即使没有创建对象实例也能访问
    3.2 类变量的访问 必须遵守 相关访问权限(private时,类名.类变量 是访问不到类变量的)
    java学习笔记 - 第十章:面向对象编程(高级部分)_第12张图片

类变量使用细节

java学习笔记 - 第十章:面向对象编程(高级部分)_第13张图片java学习笔记 - 第十章:面向对象编程(高级部分)_第14张图片

类方法

类方法快速入门

  1. 定义类方法的语法
    java学习笔记 - 第十章:面向对象编程(高级部分)_第15张图片
  2. 类方法的调用和小例子
    在这里插入图片描述
  3. 类方法快速入门的例子 - 累计学费
    3.1 类中类变量和类方法的编写
    java学习笔记 - 第十章:面向对象编程(高级部分)_第16张图片
    3.2 使用
    java学习笔记 - 第十章:面向对象编程(高级部分)_第17张图片

类方法最佳实现

不创建实例,也能调用类的方法(方法中不涉及任何和对象相关的成员 或 通用的方法)
在这里插入图片描述java学习笔记 - 第十章:面向对象编程(高级部分)_第18张图片

类方法注意事项和细节

  1. 细节1-3
    java学习笔记 - 第十章:面向对象编程(高级部分)_第19张图片
  2. 细节4-6
    java学习笔记 - 第十章:面向对象编程(高级部分)_第20张图片
    java学习笔记 - 第十章:面向对象编程(高级部分)_第21张图片

类成员小练习

  1. 练习一
    访问类变量 访问的是同一个地址 !
    java学习笔记 - 第十章:面向对象编程(高级部分)_第22张图片
  2. 练习二
    类方法中不能访问非静态成员
    java学习笔记 - 第十章:面向对象编程(高级部分)_第23张图片
  3. 练习三
    类方法中不能用this和super
    java学习笔记 - 第十章:面向对象编程(高级部分)_第24张图片

理解main方法语法

main语法说明

java学习笔记 - 第十章:面向对象编程(高级部分)_第25张图片

main特别说明

  1. main方法中可以直接访问本类 中的静态成员直接写name,hi()
  2. main方法中不可以直接访问本类 中的非静态成员
  3. 必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员
    Main01 main01 = new Main01();
    main01.cry();

java学习笔记 - 第十章:面向对象编程(高级部分)_第26张图片

main动态传值(在idea中传参)

前面讲的是在cmd命令行中传递参数,这里讲如何在idea中传参
java学习笔记 - 第十章:面向对象编程(高级部分)_第27张图片
① 第一步
java学习笔记 - 第十章:面向对象编程(高级部分)_第28张图片
② 第二步
java学习笔记 - 第十章:面向对象编程(高级部分)_第29张图片
③ 输出
在这里插入图片描述

代码块

基本介绍及语法

  1. 基本介绍
    java学习笔记 - 第十章:面向对象编程(高级部分)_第30张图片
  2. 基本语法
    java学习笔记 - 第十章:面向对象编程(高级部分)_第31张图片

代码块的好处及快速入门例子

  1. 好处(!)
    java学习笔记 - 第十章:面向对象编程(高级部分)_第32张图片
  2. 案例
    java学习笔记 - 第十章:面向对象编程(高级部分)_第33张图片

代码块使用细节

  1. 静态代码块和普通代码块 啥时被执行
  2. 静态代码块和普通代码块 执行的顺序
  3. 执行顺序的原因
  4. 综合:继承关系时静态[代码块和属性初始化]、普通、构造方法的综合调用顺序
  5. 静态代码块 只能访问静态方法和变量,普通代码块 可以访问任意
  1. 细节1-3

解读

  • 静态代码块:对类进行初始化类加载时执行只执行一次
  • 普通代码块:可以简单理解为是构造器的补充每次创建对象都会执行(与类加载无关)
  • 重点记忆:类什么时候加载(就是什么时候执行静态代码块)
  • 类加载时,父类是先加载出来的
    java学习笔记 - 第十章:面向对象编程(高级部分)_第34张图片
  1. 细节4

解读一个类中的调用顺序:

  • 前面老师讲类属性初始化的时候讲过属性初始化顺序是:①默认初始化,②显示初始化,③构造器初始化
  • 这里讲类中代码块和属性初始化调用的顺序
  • 先调用静态代码块和静态属性初始化(优先级相同,谁在前 就先调用谁)
    public static int num = getNum();这个getNum()也是静态方法
    {//代码块}
    ③ 则会先调用getNum方法初始化静态属性,载调用静态代码块
  • 再调用普通属性和普通代码块
  • 最后调用构造器
    java学习笔记 - 第十章:面向对象编程(高级部分)_第35张图片
  1. 细节5(相当于解释了一边细节4的原因)

解读调用顺序的原因分析:

  • 先调用静态代码块和静态属性初始化的原因是:它们在类加载时就执行了,所以它们是最先调用的
  • 在创建对象时会调用 构造器,构造器中隐含了 super()和调用普通代码块,所以会先调用父类构造器(父类中又会默认调用父类隐含的内容) 然后调用自己的普通代码块
    即:顺序就变成了–>父类普通代码块+父类构造器 --> 子类 普通代码块+子类构造器
    java学习笔记 - 第十章:面向对象编程(高级部分)_第36张图片
  • 代码演示:
    java学习笔记 - 第十章:面向对象编程(高级部分)_第37张图片
  1. 细节6-7(综合:继承关系时静态[代码块和属性初始化]、普通、构造方法的综合调用顺序)

解读:

  • 类加载时:静态[代码块和属性初始化] -> 先父后子
  • 构造器中:先调用隐含内容[父类构造器+普通代码] ,再调用自己的构造器
  • 所以是:
    ① 父类 普通[代码块和属性初始化] -> 父类构造器
    ② 子类 普通[代码块和属性初始化] -> 子类构造器
    java学习笔记 - 第十章:面向对象编程(高级部分)_第38张图片
    在这里插入图片描述

代码块小练习

  1. 练习1
    java学习笔记 - 第十章:面向对象编程(高级部分)_第39张图片
  2. 练习二(注意:这里没有继承关系哦)
    java学习笔记 - 第十章:面向对象编程(高级部分)_第40张图片

单例设计模式

设计模式的介绍

java学习笔记 - 第十章:面向对象编程(高级部分)_第41张图片

单例模式的介绍

java学习笔记 - 第十章:面向对象编程(高级部分)_第42张图片

单例模式饿汉式

叫饿汉式是因为:在类加载时就创建了单例对象,即使不使用,这个对象仍存在,显得很着急,所以叫饿汉

解读三部曲:

  1. 如果没将构造器私有化,则可以new好几个对象
    private GirlFriend(String name){---}
  2. 若构造器私有化,则不能在外部创建对象,只能在类的内部创建私有对象
    private GirlFriend gf = new GirlFriend("小红红")
  3. 外部不能访问这个私有对象
  4. 所以必须在类中提供一个公共的static方法,返回gf对象(为了能在静态方法中 返回gf对象,需要将其修饰为static)
    public static GirlFriend getInstance(){return gf;}
  5. 获取对象GirlFriend instance = GirlFriend.getInstance();

java学习笔记 - 第十章:面向对象编程(高级部分)_第43张图片

单例模式懒汉式

懒汉式 只有在对象使用getInstance时,才返回单例对象,后面再调用时,会返回上次创建的单例对象,从而实现单例模式

三部曲

  1. 构造器私有化
  2. 定义一个静态属性对象(定义而不赋值,在调用返回对象的方法中再赋值,这样就可以解决 饿汉式存在的问题)
  3. 提供一个public的static方法,可以返回一个对象
    java学习笔记 - 第十章:面向对象编程(高级部分)_第44张图片

饿汉和懒汉的小结和区别

  1. 区别
    java学习笔记 - 第十章:面向对象编程(高级部分)_第45张图片
    懒汉式的线程安全问题

java学习笔记 - 第十章:面向对象编程(高级部分)_第46张图片
2. 小结
java学习笔记 - 第十章:面向对象编程(高级部分)_第47张图片

final关键字

final基本介绍

java学习笔记 - 第十章:面向对象编程(高级部分)_第48张图片

final注意事项和细节

  1. 细节1-5
    java学习笔记 - 第十章:面向对象编程(高级部分)_第49张图片
  2. 细节6-9
    java学习笔记 - 第十章:面向对象编程(高级部分)_第50张图片

final小练习

java学习笔记 - 第十章:面向对象编程(高级部分)_第51张图片

抽象类

引出抽象类

java学习笔记 - 第十章:面向对象编程(高级部分)_第52张图片

抽象类快速入门

  1. 一般来说,抽象类会被继承,由它的子类来实现抽象方法
  2. 抽象方法没有方法体
  3. 一个类中有抽象方法,则该类一定是抽象类

java学习笔记 - 第十章:面向对象编程(高级部分)_第53张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第54张图片

抽象类的介绍

java学习笔记 - 第十章:面向对象编程(高级部分)_第55张图片

抽象类的细节

  1. 细节1-4
    java学习笔记 - 第十章:面向对象编程(高级部分)_第56张图片
  2. 细节5-7
    java学习笔记 - 第十章:面向对象编程(高级部分)_第57张图片
  3. 细节8
    ①. final类不能被继承,final方法也不能被重写
    ②. static 与方法重写无关
    ③. private方法访问不到
    在这里插入图片描述

抽象类小练习(易)

java学习笔记 - 第十章:面向对象编程(高级部分)_第58张图片
抽象类
java学习笔记 - 第十章:面向对象编程(高级部分)_第59张图片
实现类
java学习笔记 - 第十章:面向对象编程(高级部分)_第60张图片

模板设计模式–> 抽象类最佳实践

模板设计模式引出及步骤

java学习笔记 - 第十章:面向对象编程(高级部分)_第61张图片

引出的过程及设计模式讲解

  1. 最先想到的应该是每一个类的方法中 都写
    //得到开始时间 //完成任务代码 //得到结束时间 // 计算所用时间
    这种方法使得 重复的代码每次都要写,造成冗余
    java学习笔记 - 第十章:面向对象编程(高级部分)_第62张图片
  2. 所以想到将公共部分提取到一个新方法中,再和job方法进行组合
    但是 如果其它类不能使用这个新方法,还得在其它类中重复这个新方法,所以就想到了 继承抽象方法
    在这里插入图片描述
  3. 模板设计模式 把这个公共方法写到抽象类中,但是job方法现在还不知道怎么完成,所以job()定义为抽象方法让子类继承抽象类子类中实现job()这个抽象方法
    java学习笔记 - 第十章:面向对象编程(高级部分)_第63张图片
  4. 模板设计模式的简略结构
    java学习笔记 - 第十章:面向对象编程(高级部分)_第64张图片
  5. 模板设计部模式的步骤
    java学习笔记 - 第十章:面向对象编程(高级部分)_第65张图片

引申 for循环 快捷模板:

args.length.for 然后回车
生成:
for (int i = 0; i < args.length; i++) {
          
}

引申:获取当前时间

java学习笔记 - 第十章:面向对象编程(高级部分)_第66张图片

接口

接口快速入门

java学习笔记 - 第十章:面向对象编程(高级部分)_第67张图片

  1. 写一个接口usb
  2. 写两个类(phone和camera)实现接口
  3. 写一个类(computer)使用该接口(接口作为形参传入)

java学习笔记 - 第十章:面向对象编程(高级部分)_第68张图片

接口基本介绍

  1. 介绍
    java学习笔记 - 第十章:面向对象编程(高级部分)_第69张图片

  2. 接口中,抽象方法 可以省略abstract
    java学习笔记 - 第十章:面向对象编程(高级部分)_第70张图片

  3. 一个类实现 接口,就要实现接口的所有方法
    java学习笔记 - 第十章:面向对象编程(高级部分)_第71张图片

接口的应用场景

java学习笔记 - 第十章:面向对象编程(高级部分)_第72张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第73张图片

接口使用细节

  1. 细节1-4

① 快捷键:alt+enter 快速把要实现的方法写出来
② 接口中的方法默认是public abstract;

java学习笔记 - 第十章:面向对象编程(高级部分)_第74张图片
2. 细节5-9

① 一个类可以实现多个接口:
class A implement IB,IC{}
Java是单继承的,一个类只能继承一个类,但可以实现多个接口
② 接口不能继承其他类,但可以继承多个别的接口
③ 接口中的属性默认是public static final
也就是接口中属性 不能被修改,能直接用接口名访问

java学习笔记 - 第十章:面向对象编程(高级部分)_第75张图片

接口的小练习1

java学习笔记 - 第十章:面向对象编程(高级部分)_第76张图片

接口vs继承

在这里插入图片描述

  1. 形象描述

① 继承是is a的关系,小猴子继承老猴子,所以小猴子天生就会爬树(拥有全部父类属性和方法)

  • java是单继承的,小猴子不能同时继承鸟,鱼
  • 要想实现别的功能,可以通过 实现接口

② 小猴子要游泳,则要实现接口中的方法
③ 小猴子要飞翔,则要实现接口中的方法
④ 所以,接口(like a) 可以简单的看作是 对继承的一种补充

java学习笔记 - 第十章:面向对象编程(高级部分)_第77张图片

public class Excise {
    public static void main(String[] args) {
        LittleMoney littleMoney = new LittleMoney("悟空");
        //继承父类的爬树
        littleMoney.club();
        //实现Fish接口的方法
        littleMoney.swimming();
        //实现Bird接口的方法
        littleMoney.flying();
    }
}

class Money {
    private String name;

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

    public void club() {
        System.out.println(name + "会爬树");
    }

    public String getName() {
        return name;
    }
}

//继承
class LittleMoney extends Money implements Fish, Bird {

    public LittleMoney(String name) {
        super(name);
    }

    //实现接口中的方法
    @Override
    public void swimming() {
        System.out.println(getName() + "通过学习,学会了游泳...");
    }

    @Override
    public void flying() {
        System.out.println(getName() + "通过学习,学会了飞翔...");
    }
}

//接口
interface Fish {
    void swimming();
}

interface Bird {
    void flying();
}
  1. 实现接口 vs 继承类
    java学习笔记 - 第十章:面向对象编程(高级部分)_第78张图片

接口多态特性

java学习笔记 - 第十章:面向对象编程(高级部分)_第79张图片

接口的多态传递

  • 如果IG 继承了IH 接口,而Teacher 类实现了 IG接口
  • 那么,实际上相当于Teacher 类也实现了IH 接口
  • 这就是接口多态传递

java学习笔记 - 第十章:面向对象编程(高级部分)_第80张图片

接口的小练习2

  1. 练习题
    java学习笔记 - 第十章:面向对象编程(高级部分)_第81张图片

  2. 修改
    java学习笔记 - 第十章:面向对象编程(高级部分)_第82张图片

类定义的进一步完善

java学习笔记 - 第十章:面向对象编程(高级部分)_第83张图片

四种内部类

基本介绍

内部类是重点,也是难点,后面看源码有很多内部类

类的五大成员
java学习笔记 - 第十章:面向对象编程(高级部分)_第84张图片

四种内部类

java学习笔记 - 第十章:面向对象编程(高级部分)_第85张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第86张图片

局部内部类

  1. 细节1-5

① 位置:方法或代码块中

  • 相当于局部变量(局部变量不能加访问修饰符)
  • 可以直接访问全局变量(包含私有的)

② 作用域:仅在定义它的方法或代码块中

  • 外部
  • 外部其他类不能访问局部内部类

③本质:本质仍是一个类

java学习笔记 - 第十章:面向对象编程(高级部分)_第87张图片
在这里插入图片描述
2. 细节6-7
java学习笔记 - 第十章:面向对象编程(高级部分)_第88张图片

匿名内部类(重要!!!)

匿名内部类的本质(基于接口)

① 这个内部类就是Outer04$1,直接在创建时写上类中的内容new 接口(){ 实现方法 }
② 就相当于new Tiger(),然后再写tiger类实现IA 接口,再写实现的方法

java学习笔记 - 第十章:面向对象编程(高级部分)_第89张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第90张图片

tiger对象接收了匿名类的地址,可以使用很多次,
但是Outer04$1这个类只能使用一次(不能再调用)

在这里插入图片描述

匿名内部类的使用(普通类、抽象类)

  1. 创建继承普通类的匿名内部类
    new Father("jack"){//内容};
    1.1 (“jack”)参数列表会传递给 构造器
  2. 创建继承抽象的匿名内部类
    new Animal(){//实现抽象类方法};
  3. 创建实现接口的匿名内部类
    new IA(){//实现接口方法};
  4. 涉及到 继承,多态,动态绑定,内部类

java学习笔记 - 第十章:面向对象编程(高级部分)_第91张图片

匿名内部类的细节

  1. 细节2
    java学习笔记 - 第十章:面向对象编程(高级部分)_第92张图片
  2. 细节3-6
    java学习笔记 - 第十章:面向对象编程(高级部分)_第93张图片
  3. 细节7-8
    在这里插入图片描述

匿名内部类的最佳实践

  1. 匿名内部类当作实参直接传递,简洁高效
public class Excise {
    public static void main(String[] args) {
        //匿名内部类当作实参直接传递,简洁高效
        m(new IA() {
            @Override
            public void show() {
                System.out.println("匿名内部类中重写接口的show方法");
            }
        });
        //传统方法
        Picture picture = new Picture();
        m(picture);
    }
    //静态方法,形参是接口类型
    public static void m(IA ia){
        ia.show();
    }
}

//接口
interface IA{
    void show();
}
//传统方法-类-->实现接口 => 在编程领域称为硬编码
class Picture implements IA{

    @Override
    public void show() {
        System.out.println("传统方法重写接口的show方法");
    }
}

小练习

java学习笔记 - 第十章:面向对象编程(高级部分)_第94张图片

public class Excise {
    public static void main(String[] args) {
        CellPhone cellPhone = new CellPhone();
        cellPhone.alarm(new Bell() {
            @Override
            public void ring() {
                System.out.println("小懒猪起床了");
            }
        });
        cellPhone.alarm(new Bell() {
            @Override
            public void ring() {
                System.out.println("小伙伴上课了");
            }
        });
    }
}

interface Bell{
    void ring();
}

class CellPhone{
    public void alarm(Bell bell){
        bell.ring();
    }
}

成员内部类

  1. 细节1-2
    java学习笔记 - 第十章:面向对象编程(高级部分)_第95张图片
  2. 细节3-6

访问外部类成员,比如属性name,则new Outer().name
对于成员内部类也是一样的new Outer().new Inner();
普通成员不能通过类名直接访问,得先创建外部类对象,再通过外部类对象创建成员内部类对象当然是不能写成new new Outer().Inner()
java学习笔记 - 第十章:面向对象编程(高级部分)_第96张图片
外部其他类访问成员内部类的两种方法
java学习笔记 - 第十章:面向对象编程(高级部分)_第97张图片

  1. 细节7
    java学习笔记 - 第十章:面向对象编程(高级部分)_第98张图片

静态内部类

java学习笔记 - 第十章:面向对象编程(高级部分)_第99张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第100张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第101张图片
java学习笔记 - 第十章:面向对象编程(高级部分)_第102张图片

本章作业

作业1(static)

java学习笔记 - 第十章:面向对象编程(高级部分)_第103张图片

作业2(题意->代码(静态属性))

java学习笔记 - 第十章:面向对象编程(高级部分)_第104张图片

/**
 * @author 王胖子
 * @version 1.0
 */
public class Excise {
    public static void main(String[] args) {
        System.out.println(Frock.getNextNum());//100100
        System.out.println(Frock.getNextNum());//100200
        Frock frock1 = new Frock();
        Frock frock2 = new Frock();
        Frock frock3 = new Frock();
        System.out.println(frock1.getSeriaNumber());//100300
        System.out.println(frock2.getSeriaNumber());//100400
        System.out.println(frock3.getSeriaNumber());//100500
    }
}

class Frock {
    private static int currentNum = 100000;//出场序列号的起始值
    private int seriaNumber;

    public Frock() {
        this.seriaNumber = getNextNum();
    }

    public static int getNextNum() {//生成上衣唯一序列号的方法
        currentNum += 100;
        return currentNum;
    }

    public int getSeriaNumber() {
        return seriaNumber;
    }
}

作业3(匿名内部类作为参数)

在这里插入图片描述

匿名内部类最经典的用法就是作为参数

  1. 普通传参方法:先创建一个实现了ICalculate接口的类,再创建该类的对象,把该对象作为参数传入test方法中
  2. 匿名内部类方法:直接传入一个实现了ICalculate接口的匿名内部类即可
    该匿名内部类可以灵活的实现work,完成不同的计算任务
/**
 * @author 王胖子
 * @version 1.0
 */
public class Excise {
    public static void main(String[] args) {
        //匿名内部类省去了 创建类实现接口效率低的麻烦
        /*
            匿名内部类是实现了接口的类,同时也是一个对象
            编译类型是ICalculate(),运行类型是匿名内部类
            new ICalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1 +n2;
            }
         */
        CellPhone cellPhone = new CellPhone();
        cellPhone.testWork(new ICalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1 + n2;
            }
        }, 10, 20);
    }
}

//接口类
interface ICalculate {
    //完成计算(用匿名内部类来实现)
    public double work(double n1, double n2);
}

class CellPhone {
    //解读:
    //普通传参方法:先创建一个实现了ICalculate接口的类,再创建该类的对象,把该对象作为参数传入test方法中
    //匿名内部类方法:直接传入一个实现了ICalculate接口的匿名内部类即可
    //该匿名内部类可以灵活的实现work,完成不同的计算任务
    public void testWork(ICalculate iCalculate, double n1, double n2) {
        double result = iCalculate.work(n1, n2);//动态绑定运行类型(上面的匿名内部类)
        System.out.println("计算后的结果是 = " + result);
    }
}

作业4(局部内部类的使用)

/**
 * @author 王胖子
 * @version 1.0
 */
public class Excise {
    public static void main(String[] args) {
        A a = new A();
        a.method();
    }
}

class A {
    private String NAME = "小瘦子";

    public void method() {
        //局部内部类定义在方法或代码块中
        //使用:在类中创建内部类对象,调用内部类方法
        //可以直接访问外部类内容(包括私有的)
        //当内部类和外部类的属性重名时 可以通过外部类.this.属性名来访问外部类属性
        class B {
            private final String NAME = "小胖子";

            void show() {
                System.out.println("B类中的NAME = " + NAME + "\n" + "A类中的name = " + A.this.NAME);
            }
        }
        B b = new B();
        b.show();
    }
}

作业5(工厂类)

java学习笔记 - 第十章:面向对象编程(高级部分)_第105张图片

/**
 * @author 王胖子
 * @version 1.0
 */
public class Excise {
    public static void main(String[] args) {
        Person person = new Person("唐僧", new Horse());
        person.common();
        person.passRiver();
        person.passRiver();
    }
}

//抽象产品接口
interface Vehicles {
    public void work();
}

//具体产品类
class Horse implements Vehicles {
    @Override
    public void work() {
        System.out.println("一般情况,用马走");
    }
}

class Boat implements Vehicles {
    @Override
    public void work() {
        System.out.println("过河时,用船走");
    }
}

//工厂类
class Factory {
    //方法定义为静态
    //马只有一匹,用单例设计模式-饿汉式
    private Horse horse = new Horse();

    private Factory() {
    }

    public static Vehicles getHorse() {
        return new Horse();
    }

    public static Vehicles getBoat() {
        return new Boat();
    }
}

//人(整合)
class Person {
    private String name;
    private Vehicles vehicles;

    public Person(String name, Vehicles vehicles) {
        this.name = name;
        this.vehicles = vehicles;
    }

    public void common() {
        //如果vehicles的运行类型不是Horse,则用工厂类返回一个马对象
        if (!(vehicles instanceof Horse)) {
            vehicles = Factory.getHorse();
        }
        vehicles.work();
    }

    public void passRiver() {
        //如果vehicles的运行类型不是Boat,则用工厂类返回一个船对象
        if (!(vehicles instanceof Boat)) {
            vehicles = Factory.getBoat();
        }
        vehicles.work();
    }
}

作业6(成员内部类)

  1. 类与成员内部类 体现类与类的包含关系
  2. 成员内部类 在外部其他类中使用可以调用外部类中的get方法获取内部类的对象
    public Air getAir() {
    return new Air();
    }

在这里插入图片描述

/**
 * @author 王胖子
 * @version 1.0
 */
public class Excise {
    public static void main(String[] args) {
        //实例化不同的car对象
        Car car = new Car(26);
        car.getAir().flow();
        Car car1 = new Car(41);
        car1.getAir().flow();
        Car car2 = new Car(41);
        car2.getAir().flow();
    }
}

class Car {
    private double template;

    public Car(double template) {
        this.template = template;
    }

    //air 成员内部类
    class Air {
        public void flow() {
            if (template > 40) {
                System.out.println("温度大于40,吹冷风");
            } else if (template < 0) {
                System.out.println("温度小于0,吹热风");
            } else {
                System.out.println("温度正常,关闭空调");
            }
        }
    }

    public Air getAir() {
        return new Air();
    }
}

你可能感兴趣的:(java基础学习笔记,java,开发语言,后端)