Java学习基础笔记——面向对象

第七章 面向对象基础

7.1 访问修饰符

7.1.1 基本介绍

7.1.2 注意事项 

7.2 面向对象三大特征(封装、继承和多态)

7.2.1 封装介绍

7.2.1.1 封装的好处

7.2.1.2 封装的实现步骤

7.2.2 继承

7.2.2.1 继承基本介绍

7.2.2.2 继承的基本语法

7.2.2.3 继承细节 

7.2.3 多态

7.2.3.1 多态介绍

7.2.3.2 对象的多态

7.2.3.3 多态细节

7.2.3.3.1 多态的向上转型

7.2.3.3.2 多态的向下转型

7.2.3.3.3 多态的注意事项

7.2.4 java的动态绑定机制

7.2.5 多态的应用

7.2.5.1 多态数组

7.2.5.2 多态参数

7.3 Super关键字

7.3.1 基本介绍

7.3.2 基本语法

7.3.3 super 编程细节

7.3.4 super 和 this 比较

7.4 方法重写(override)

7.4.1 基本介绍

7.4.2 方法重写注意事项

7.5 Object类详解,垃圾回收机制

7.5.1 equals方法

7.5.2 hashCode 方法

7.5.3 toString方法

7.5.4 finalize方法

7.6 断点调试

7.6.1 断点调试介绍

第八章 面向对象进阶

8.1 类变量和类方法

8.1.1 类变量的内存布局

8.1.2 什么是类变量

8.1.3 如何定义类变量

8.1.4 如何访问类变量

8.1.5 类变量使用细节

8.1.6 类方法基本介绍

8.1.7 类方法的调用

8.1.8 类方法的经典使用场景

8.1.9 类方法使用细节

8.2 理解main方法语法

8.2.1 深入理解main方法

8.3 代码块

8.3.1 基本介绍

8.3.2 基本语法

8.3.3 代码块的好处

8.3.4 代码块使用细节

8.4 单例设计模式

8.4.1 什么是设计模式

8.4.2 什么是单例模式

8.5 final关键字

8.5.1 基本介绍

8.5.2 final 使用细节

8.6 抽象类

8.6.1 抽象类的介绍

8.6.2 抽象类使用细节

8.6.3 抽象类

8.6.3.1 基本介绍

8.6.3.2 模板设计模式能解决的问题

8.7 接口

8.7.1 基本介绍

8.7.2 使用细节

8.7.3 实现接口 & 继承类

8.7.4 接口的多态特性

8.8 内部类

8.8.1 基本介绍

8.8.2 基本语法

8.8.3 内部类的分类

8.8.3.1 局部内部类的使用

8.8.3.2 匿名内部类的使用

8.8.3.2.1 匿名内部类的基本语法

8.8.3.2.2 匿名内部类的使用细节  ->  <多态、继承、动态绑定机制、内部类>

8.8.3.3 成员内部类的使用

8.8.3.4 静态内部类的使用

第七章 面向对象基础

7.1 访问修饰符

7.1.1 基本介绍

java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围)

  • 公开级别:用public 修饰,对外公开

  • 受保护级别:用protected 修饰,对子类和同一个包中的类公开

  • 默认级别:没有修饰符号,向同一个包的类公开

  • 私有级别:用private 修饰,只有类本身可以访问,不对外公开

  • 访问权限

访问级别访问控制修饰符同类同包子类不同包
公开public
受保护protected×
默认无修饰符××
私有private×××

7.1.2 注意事项 

  • 修饰符可以用来修饰类中的属性,成员方法以及类

  • 只有 默认和public 才能修饰类,并且遵循上述访问权限的特点

  • 成员方法的访问规则和属性完全一样

7.2 面向对象三大特征(封装、继承和多态)

7.2.1 封装介绍

  • 封装(encapsulation)就是把抽象出的数据[属性],和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作

7.2.1.1 封装的好处
  • 隐藏实现细节 方法(连接数据库) -> 调用(传入参数...)

  • 可以对数据进行验证,保证安全合理

7.2.1.2 封装的实现步骤
  • 将属性进行私有化private 【不能直接修改属性】

  • 提供一个公共的 (public) set 方法,用于对属性判断并赋值

    public void setXxx (类型 参数名) {

    //加入数据验证的业务逻辑

    属性 = 参数名;

    }

  • 提供一个公共的get 方法,用于获取属性的值

    public XX getXxx ( ) { //权限判断

        return xx;

    }

7.2.2 继承

7.2.2.1 继承基本介绍
  • 继承 extends 可以解决代码复用,让我们的编程更加靠近人类思维。当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends 来声明继承父类即可

7.2.2.2 继承的基本语法
  • class 子类 extends 父类 {

    }

    • 子类就会自动拥有父类定义的属性和方法

    • 父类又叫 超类, 基类

    • 子类又叫 派生类

7.2.2.3 继承细节 
  • 子类继承了所有的属性和方法,但是私有属性和方法不能在子类中直接访问,要通过父类提供公共的方法取访问

  • 子类必须调用父类的构造器,完成父类的初始化

  • 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过

  • 如果希望指定去调用父类的某个构造器,则显示的调用一下:super(参数列表)

  • super 在使用时,必须放在构造器第一行(super只能在构造器中使用)

  • super( ) 和 this( ) 都只能放在构造器第一行,因此这两个方法不能共同存在于一个构造器

  • java所有类都是Object 类的子类,Object是所有类的基类 / 超类

  • 父类构造器的调用不限于直接父类!将一直往上追溯直到Object类

  • 子类最多只能继承一个父类(指的是 直接继承),即 java 中是单继承机制

  • 不能滥用继承,子类和父类直接必须满足 is - a 的逻辑关系

7.2.3 多态

7.2.3.1 多态介绍
  • 方法或对象具有多种形态, 是面向对象的第三大特征,多态是建立在封装和继承基础之上的

7.2.3.2 对象的多态
  • 一个对象的编译类型和运行类型可以不一致

  • 编译类型在定义对象时,就确定了,不能改变

  • 运行类型是可以变化的

  • 编译类型看定义时 = 号 的左边, 运行类型看 = 号的 右边

7.2.3.3 多态细节
  • 多态的前提是:两个对象(类)存在继承关系

7.2.3.3.1 多态的向上转型
  • 本质:父类的引用指向了子类的对象

  • 语法:父类类型 引用名 = new 子类类型();

  • 特点:

    • 编译类型看左边,运行类型看右边

    • 可以调用父类中的所有成员(需遵守访问权限)

    • 不能调用子类中特有成员

    • 最终运行效果看子类的具体实现!

7.2.3.3.2 多态的向下转型
  • 语法:子类类型 引用名 = (子类类型) 父类引用;

  • 只能强转父类的引用,不能强转父类的对象

  • 要求父类的引用必须指向的是当前目标类型的对象

  • 当向下转型后,可以调用子类类型中所有的成员

7.2.3.3.3 多态的注意事项
  • 属性没有重写之说!  ->   属性的值看编译类型

  • instanceof 比较操作符,用于判断对象的(运行)类型是否为XX类型或XX类型的子类型

7.2.4 java的动态绑定机制

  • 当调用对象方法的时候,该方法会和该对象的内存地址(运行类型)绑定

  • 当调用对象属性时,没有动态绑定机制

7.2.5 多态的应用

7.2.5.1 多态数组
  • 数组的定义类型为父类类型,里面保存的实际元素类型为子类类型 

7.2.5.2 多态参数
  • 方法定义的形参类型为父类类型,实参类型允许为子类类型 

7.3 Super关键字

7.3.1 基本介绍

  • super 代表父类的引用,用于访问父类的属性、方法、构造器

7.3.2 基本语法

  • 访问父类的属性,但不能访问父类的private 属性

    super.属性名;

  • 访问父类的方法,不能访问父类的private 方法

    super.方法名(参数列表);

  • 访问父类的构造器

    super(参数列表); 只能放在构造器的第一句,且只能出现一句

7.3.3 super 编程细节

  • 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化)

  • 当子类中有 和 父类中的成员 (属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果

  • super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类(上级类)中都有同名的成员,使用super 访问遵循就近原则。A -> B -> C, 当然也需要遵守访问权限的相关规则

7.3.4 super 和 this 比较

No.区别点thissuper
1访问属性访问本类中的属性,如果本类没有此属性则从父类中继续查找从父类开始查找属性
2调用方法访问本类中的方法,如果本类没有此方法则从父类中继续查找从父类开始查找方法
3调用构造器调用本类构造器,必须放在构造器的首行调用父类构造器,必须放在子类构造器的首行
4特殊表示当前对象子类中访问父类对象

7.4 方法重写(override)

7.4.1 基本介绍

  • 简单讲:方法重写(覆盖)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法

7.4.2 方法重写注意事项

  • 子类的方法的参数,方法名称,要和父类方法的参数,方法名称完全一样

  • 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类

  • 子类方法不能缩小父类方法的访问权限

7.5 Object类详解,垃圾回收机制

7.5.1 equals方法

  • ==:既可以判断基本类型,又可以判断引用类型

  • ==:如果判断基本类型,判断的是值是否相等。例:int i = 10; double d = 10.0;

  • ==:如果判断引用类型,判断的是地址是否相等,即 判断是不是同一个对象

  • equals:是Obiect 类中的方法,只能判断引用类型

  • 默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。

7.5.2 hashCode 方法

  • 提高具有哈希结构的容器效率

  • 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的

  • 两个引用,如果指向的是不同对象,则哈希值是不一样的

  • 哈希值主要根据地址号来的!,不能完全将哈希值等价于地址

  • 后面在集合中hashCode 如果需要的话,也会重写

7.5.3 toString方法

  • 基本介绍

    • 默认返回:全类名+@+哈希值的十六进制,子类往往重写toString方法,用于返回对象的属性信息

  • 重写toString 方法,打印对象或拼接对象时,都会自动调用该对象的toString 形式

  • 当直接输出一个对象时,toString 方法会被默认的调用

7.5.4 finalize方法

  • 当对象被回收时,系统自动调用该对象的finalize 方法。子类可以重写该方法,做一些释放资源的操作

  • 什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法

  • 垃圾回收机制的调用,是由系统来决定(即 有自己的 gc 算法),也可以通过System.gc( )主动触发垃圾回收机制

7.6 断点调试

  • 在断点调试过程中,是运行状态,是以对象的 运行类型来执行的

7.6.1 断点调试介绍

  • 断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即 显示错误,停下。 进行分析从而找到这个Bug

  • 断点调试也能帮助我们查看java 底层源码的执行过程,提高能力

第八章 面向对象进阶

8.1 类变量和类方法

8.1.1 类变量的内存布局

  • 不论static变量在哪里,目前说法:(有的说在方法区,有的说在静态域,与 jdk 的版本有关)

    1. static 变量是同一个类的所有对象共享

    2. static 类变量,在类加载的时候就生成了

8.1.2 什么是类变量

  • 类变量也叫静态变量(静态属性),是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量

8.1.3 如何定义类变量

  • 定义语法:

    访问修饰符 static 数据类型 变量名;[推荐]

    static 访问修饰符 数据类型 变量名;

8.1.4 如何访问类变量

  • 类名.类变量名[推荐] 或者 对象名.类变量名 [静态变量的访问修饰符的访问权限和范围 和 普通属性是一样的]

8.1.5 类变量使用细节

  • 什么时候需要用类变量

    • 当我们需要让某个类的所有对象都共享一个变量时,就可以考虑使用类变量(静态变量):比如, 定义学生类,统计所有学生共交多少q。 Student(name, static fee)

  • 类变量与实例变量(普通属性)区别

    • 类变量是该类的所有对象共享的,而实例变量是每个对象独享的

  • 加上static 称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量

  • 类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,推荐使用 类名.类变量名 方式访问【前提是 必须遵守相应的访问权限】

  • 实例变量不能通过 类名.类变量名 方式访问

  • 类变量是在类加载时就初始化了,也就是说,即使你没有创建对象,只要类加载了,就可以使用类变量了

  • 类变量的生命周期是随类的加载开始,随着类的消亡而销毁

8.1.6 类方法基本介绍

  • 类方法也叫静态方法。 形式如下:

    访问修饰符 static 数据返回类型 方法名(){ } [推荐]

    static 访问修饰符 数据返回类型 方法名(){ }

8.1.7 类方法的调用

  • 使用方式:类名.类方法名 或者 对象名.类方法名 

8.1.8 类方法的经典使用场景

  • 当方法中不涉及任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率

  • 比如:工具类中的方法 utils -------Math类、Arrays类、Collections 集合类 看下源码

  • 小结

    • 在实际开发,往往会将一些通用的方法,设计成静态方法,这样我们不需要创建对象就可以使用了,比如,打印一维数组,冒泡排序,完成某个计算任务 等..

8.1.9 类方法使用细节

  • 类方法和普通方法都是随着类的加载而加载,将结构信息存储在方法区:

    类方法中无 this 的参数

    普通方法中隐含着 this 的参数

  • 类方法可以通过类名调用,也可以通过对象名调用

  • 普通方法和对象有关,需要通过对象名调用,比如:对象名.方法名(参数),不能通过类名调用

  • 类方法中不允许使用和对象有关的关键字,比如this和super。普通方法(成员方法)可以

  • 类方法(静态方法)中 只能访问 静态变量 或 静态方法

  • 普通成员方法,既可以访问 普通变量(方法),也可以访问静态变量(方法)

  • 小结

    • 静态方法,只能访问静态的成员

    • 非静态的方法,可以访问静态成员和非静态成员 ----- 必须遵守访问权限

8.2 理解main方法语法

8.2.1 深入理解main方法

解释main方法的形式:public static void main(String [] args) {}

  • 1.main()方法是java虚拟机调用的

  • 2.java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是public

  • 3.java虚拟机在执行main()方法时不必创建对象,所以该方法必须是static

  • 4.该方法接收String 类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数

  • 特别提示

    • 在main()方法中,我们可以直接调用main方法所在类的静态方法或静态属性

    • 但是,不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员。

8.3 代码块

8.3.1 基本介绍

  • 代码化块又称为初始化块,属于类中的成员[即 是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过{ }包围起来

  • 但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用

8.3.2 基本语法

  • [修饰符] {

    代码

    };

    • 注意:

      • 修饰符 可选,要写的话,也只能写 static

      • 代码块分为两类,使用static 修饰的叫静态代码块,没有static 修饰的,叫普通代码块

      • 逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)

      • ; 号可以写上,也可以省略

8.3.3 代码块的好处

  • 相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作

  • 如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性

8.3.4 代码块使用细节

  • static 代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行。

  • 类什么时候被加载

    • 创建对象实例时 (new)

    • 创建子类对象实例,父类也会被加载

    • 使用类的静态成员时(静态属性,静态方法)

  • 普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。如果只是使用类的静态成员时,普通代码块并不会执行  ---  普通代码块类似于构造器

  • 创建一个对象时,在一个类 调用顺序是:

    • 调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)

    • 调用普通代码块和普通属性(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)

    • 调用构造方法

  • 构造方法(构造器)的最前面其实隐含了 super( )和 调用普通代码块,新写一个类演示 -- 静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优先于 构造器和普通代码块执行的

  • 我们看一下创建一个子类时 (继承关系) ,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

    • 父类的静态代码块和静态属性(优先级一样,按定义顺序执行)

    • 子类的静态代码块和静态属性(优先级一样,按定义顺序执行)

    • 父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

    • 父类的构造方法

    • 子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

    • 子类的构造方法

  • 静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员

8.4 单例设计模式

8.4.1 什么是设计模式

  • 静态方法和属性的经典使用

  • 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己再思考和摸索

8.4.2 什么是单例模式

  • 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例得方法

  • 单例(单个的实例)模式有两种方式:

    • 饿汉式

      • 演示单例模式得实现,步骤如下:

        • 构造器私有化 ----防止直接 new

        • 类的内部创建对象

        • 向外暴露一个静态的公共方法 ----getInstance

        • 代码实现

    • 懒汉式

      • 仍然构造器私有化

      • 定义一个 static 静态属性对象

      • 提供一个 public 的 static 方法,可以返回一个 Cat 对象

      • 懒汉式,只有当用户使用getInstance时,才返回cat对象,后面再次调用时,会返回上次创建的对象

    • 饿汉式 VS 懒汉式

      • 二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建

      • 饿汉式不存在线程安全问题,,懒汉式存在线程安全问题

      • 饿汉式存在浪费资源的可能,因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题

      • 在javaSE标准类中,java.lang.Runtime 就是经典的单例模式

8.5 final关键字

8.5.1 基本介绍

final 可以修饰类、属性、方法和局部变量

在某些情况下,程序员可能有以下需求,就会用到final

  • 当不希望类被继承时,可以用final 修饰

  • 当不希望父类的某个方法被子类覆盖/重写(override)时,可以用final 关键字修饰

  • 当不希望类的某个属性的值被修改,可以用final 修饰

  • 当不希望某个局部变量被修改,可以使用final 修饰

8.5.2 final 使用细节

  • final 修饰的属性又叫常量,一般 用 XX_XX_XX来命名

  • final 修饰的属性在定义时,必须赋初值,并且以后不能再修改,赋值可以在如下位置之一

    • 定义时:如 public final double TAX_RATE = 0.08;

    • 在构造器中

    • 在代码块中

  • 如果final 修饰的属性是静态的,则初始化的位置只能是(1)定义时(2)在静态代码块 不能再构造器中赋值

  • final 类不能继承,但是可以实例化对象

  • 如果类不是final 类,但是含有final 方法,则该方法虽然不能重写,但是可以被继承

  • 一般说来,如果一个类已经是final 类了,就没有必要再将方法修饰成final 方法

  • final 不能修饰构造方法(即构造器)

  • final 和 static 往往搭配使用,效率更高,底层编译器做了优化处理!----------搭配使用可以不让类加载,而且属性 final 和 static 顺序可互换

  • 包装类(Integer,Double,Float,Boolean等都是final ),String 也是 final 类

8.6 抽象类

当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,则这个类就是抽象类

8.6.1 抽象类的介绍

  • 用abstract 关键字来修饰一个类时,这个类就叫抽象类 访问修饰符 abstract 类名{ }

  • 用abstract 关键字来修饰一个方法时,这个方法就是抽象方法 访问修饰符 abstract 返回类型 方法名(参数列表); //没有方法体

  • 抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类( )

  • 抽象类,是面试官比较爱问的知识点,在框架和设计模式使用较多 

8.6.2 抽象类使用细节

  • 抽象类不能被实例化

  • 抽象类不一定要包含abstract 方法。也即是说,抽象类可以没有 abstract 方法,还可以有实现的方法

  • 一旦类包含了abstract 方法,则这个类必须声明为abstract

  • abstract 只能修饰类和方法,不能修饰属性和其它的

  • 抽象类可以有任意成员【因为抽象类还是类】,比如:非抽象方法、构造器、静态属性等

  • 抽象方法不能有主体,即不能实现

  • 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract 类

  • 抽象方法不能使用private、final 和 static 来修饰,因为这些关键字都是和重写相违背的

8.6.3 抽象类

8.6.3.1 基本介绍
  • 抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式

8.6.3.2 模板设计模式能解决的问题
  • 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现

  • 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式。

8.7 接口

8.7.1 基本介绍

  • 接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。

    语法:

    interface 接口名 {

    //属性

    //方法------<1.抽象方法、2.默认实现方法、3.静态方法>

    }

    class 类名 implements 接口 {

    自己属性;

    自己方法;

    必须实现的接口的抽象方法

    }

8.7.2 使用细节

  • 接口不能被实例化

  • 接口中所有的方法是 public 方法,接口中抽象方法,可以不用abstract 修饰

  • 一个普通类实现接口,就必须将该接口的所有方法都实现  --  使用快捷键 Alt + Enter来解决

  • 抽象类实现接口,可以不用实现接口的方法

  • 一个类同时可以实现多个接口

  • 接口中的属性,只能是final 的,而且是 public static final 修饰符。

  • 接口中属性的访问形式:接口名.属性名

  • 一个接口不能继承其他的类,但是可以继承多个别的接口

  • 接口的修饰符 只能是 public 和默认,这点和类的修饰符是一样的

8.7.3 实现接口 & 继承类

  • 接口和继承解决的问题不同

    • 继承的价值主要在于:解决代码的复用性和可维护性

    • 接口的价值主要在于:设计,设计好各种规范(方法),让其他类去实现这些方法

  • 接口比继承更加灵活

    • 接口比继承更加灵活,继承是满足 is - a 的关系,而接口只需满足 like - a 的关系

  • 接口在一定程度上实现代码解耦 [即 接口的规范性+动态绑定机制] 

  • 小结:

    • 当子类继承了父类,就自动拥有父类的功能

    • 如果子类需要扩展功能,可以通过实现接口的方式来扩展

    • 可以理解为 实现接口 是对 java 单继承机制的一种补充

8.7.4 接口的多态特性

  • 多态参数

  • 多态数组

  • 接口存在多态传递现象

8.8 内部类

img

8.8.1 基本介绍

  • 一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(out class)。是我们类的第五大成员,内部类最大的特点就是可以直接访问私有属性 ,并且可以体现类与类之间的包含关系 。

  • 类的五大成员----1.属性2.方法3.构造器4.代码块5.内部类

8.8.2 基本语法

  • class Outer { //外部类

    class Inner { //内部类

    }

    }

    class Other { //外部其他类

    }

8.8.3 内部类的分类

  • 定义在外部类局部位置上(比如方法内):

    • 局部内部类(有类名

    • 匿名内部类(无类名)

  • 定义在外部类的成员位置上:

    • 成员内部类(没用static 修饰)

    • 静态内部类(使用static 修饰)

8.8.3.1 局部内部类的使用

说明:局部内部类是定义在外部类的局部位置,比如方法中,并且有类名

  • 可以直接访问外部类的所有成员,包含私有的

  • 不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final 修饰,因为局部变量也可以使用final

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

  • 局部内部类---访问---->外部类的成员[访问方式:直接访问]

  • 外部类---访问---->局部内部类的成员

    访问方式:创建对象,再访问(注意:必须在作用域内)

  • 1.局部内部类定义在外部类的局部位置,方法中或代码块中

    2.作用域在方法体或者代码块中

    3.本质还是一个类

  • 外部其他类----不能访问----->局部内部类(因为 局部内部类地位是一个局部变量)

  • 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

    System.out.println("外部类的n2= " + 外部类名.this.n2);

8.8.3.2 匿名内部类的使用

说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名

8.8.3.2.1 匿名内部类的基本语法

    new 类或接口(参数列表){

        类体

    };

  • 1.本质是类

    2.内部类

    3.该类没有名字(是有名字的,只不过是系统分配的,类名在底层可以看到,但我们无法使用)

    4.同时还是一个对象

8.8.3.2.2 匿名内部类的使用细节  ->  <多态、继承、动态绑定机制、内部类>
  • 匿名内部类的语法比较奇特,请大家注意,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,对前面代码分析可以看出这个特点,因此可以调用匿名内部类方法

  • 可以直接访问外部类的所有成员,包含私有的

  • 不能添加访问修饰符,因为它的地位就是一个局部变量

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

  • 匿名内部类---访问--->外部类成员 [访问方式:直接访问]

  • 外部其他类---不能访问---->匿名内部类(因为 匿名内部类地位是一个局部变量)

  • 如果外部类和内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

8.8.3.3 成员内部类的使用

说明:成员内部类是定义在外部类的成员位置,并且没有static修饰

  • 1.可以直接访问外部类的所有成员,包含私有的

  • 2.可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员

  • 3.作用域:和外部类的其他成员一样,为整个类体。比如前面的案例,在外部类的成员方法中,创建成员内部类对象,在调用方法

  • 4.成员内部类 -> 访问 -> 外部类(比如:属性) [访问方式:直接访问]

  • 5.外部类 -> 访问 -> 成员内部类 [访问方式:创建对象,再访问]

  • 6.外部其他类 -> 访问 -> 成员内部类

  • 7.如果外部类和内部类的成员重名时,成员内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

8.8.3.4 静态内部类的使用

说明:静态内部类是定义在外部类的成员位置,并且有static 修饰

  • 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

  • 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员

  • 作用域:同其他的成员,为整个类体

  • 静态内部类 -> 访问 -> 外部类(比如:静态属性) [访问方式:直接访问所有静态成员]

  • 外部类 -> 访问 -> 静态内部类 访问方式: 创建对象,再访问

  • 外部其他类 -> 访问 -> 静态内部类

  • 如果外部类和静态内部类的成员重名时,静态内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值