zoukankan      html  css  js  c++  java
  • JavaOOP

    面向对象

    是什么?

    ​ 提取实际生活中一些事物的共性特征和动作,分出来。封装在一起,不同种类之间的事物相互作用。着重点在于,找到事物的共性,和相互的联系,也就是类的设计

    为啥要面向对象?

    ​ 因为大型项目开发,面向过程,程序的拓展性不高,维护成本高等等,找到事物之间的共性,和相互的联系,更符合我们的思想习惯。

    特点

    三大特征:封装、继承、多态

    一.类与对象

    是什么?

    类:是一组相关的属性和行为的集合,是同种对象的集合与抽象

    对象:是现实中该类事物的具体体现,
    一个具体的实例(个体)

    类中有什么?

    成员变量: 就是事物的属性

    成员方法: 就是事物的行为

    注:公共类的文件名必须和类名一样.一个文件里面至多只能有一个公共类。 (public),但是可以有多个class普通类

    二.成员变量和局部变量的区别

    区别一:定义的位置不同

    • 定义在类中、方法外的变量是成员变量
    • 定义在方法声明上或者方法内{}语句里面的变量是局部变量

    区别二:在内存中的位置不

    • 成员变量存储在堆内存的对象中,一般不初始化,因为堆中变量都会赋予初值

      数据类型 默认初始值
      char u0000(空)
      整型 0
      引用数据类型 null
      boolean false
      float 0.0f
      double 0.0
    • 局部变量存储在栈内存的方法中,随着方法栈帧进栈而声明,初始化。

    区别三:生命周期不同

    • 成员变量随着对象的创建而出现在堆中,随着对象的消失而从堆
      中消失
    • 局部变量随着方法的调用而出现在栈中,随着方法的弹栈(结
      束)而消失,出了方法体也消失。

    区别四:初始化不同

    • 成员变量因为在堆内存中,所有默认的初始化值
    • 局部变量没有默认的初始化值,必须先给其赋值才可以使用。

    区别五:成员变量和局部变量可以同名

    • 同名情况下,若想引用成员变量,需要在变量名前面加上this.

    *区别六:作用域不同

    • 成员变量的作用域是整个类;
    • 局部变量的作用域仅限在方法内部

    三. 匿名对象

    是什么?
    就是没有名字的对象,是对象的一种简化表示形式。即堆中新建的对象,在栈中没有变量指向它。有创建对象的语句,却没有把对象地址值赋值给某个变量。

    普通对象: Student s =new Student();
    匿名对象: new Student();

    有啥用?

    一次性作用,了解即可。

    四.封装,private和this

    是什么?
    比如,方法封装了一个代码块,封装了一个功能的实现,类封装了某类物体的属性和方法。可理解为封装。

    有啥用?

    1.隐藏类的实现细节,实现信息的隐藏,提供公共的访问方式
    2.提高了程序的模块化,便于维护
    3.提高了代码的安全性
    4.提高代码的复用性
    5.使用者只能通过事先定好的方式来访问数据,实现者可以方便地加入控制逻辑,限制使用者对属性的不合理操作。

    private关键字

    是啥?

    可以修饰成员(成员变量和成员方法)

    有啥用?

    1.被private修饰的成员只在本类中才能直接访问,类之外只能通过接
    口间接访问(getter && setter);
    2.类中不需要对外提供的内容都私有化,包括属性和方法。以后再描
    述事物,属性都私有化并提供setter && getter。

    应用场景

    1. 把成员变量用private修饰
    2. 提供对应的getXxx()/setXxx()方法,来输入/获取变量值 getter &&setter私有成员只有通过setter赋值,通过getter返回值
    3. private修饰构造方法,将无法创建对象

    this

    是啥?

    this代表所在类的对象引用。
    记住: 方法被哪个对象调用,this就代表哪个对象

    有啥用?

    局部变量和成员变量的名称相同时,局部变量会把成员变量隐藏,为了解决这个问题,需要用到this关键字。在变量名称之前加上this,表示成员变量,可以把成员变量和局部变量区分,

    例如 this.name = name;

    五.构造方法:

    是什么?

    ​ 给对象的数据进行初始化,从字面上理解即是对象创建时要执行的方法。

    有啥用?

    ​ 既然是对象创建时要执行的方法,那么只要在new对象时,知道其执行的构造方法是什么,就可以在执行这个方法的时候给对象进行属性赋值。无参构造方法创建对象时,成员变量的值不为空,而是系统默认值或显示初始化的值

    Perons p = new Person("张三",23);

    在new 的时候给p对象的name属性和age属性进行赋值,使这个对象的属性有值。

    构造方法格式:

    修饰符 构造方法名(参数列表)
    {
    }
    1.方法名与类名相同
    2.没有返回值类型,连void都没有
    3.没有具体的返回值
    4.可以有参数,也可以没有
    5.在new对象的时候会自动调用执行构造方法
    6.若构造方法被private修饰,将无法创建对象。因为无法调用构造方法

    注意事项:

    1.如果你不提供构造方法,系统会给出默认无参构造方法
    2.如果你提供了有参构造方法,系统将不再提供无参(需要自己提供一个无参构造方法),最好养成无参构造写好的习惯。
    3.构造方法也是可以重载的(和普通方法相同)
    4.构造方法不能递归调用

    六.一个基本类的标准代码写法

    类名
    成员变量
    构造方法
    a.无参构造方法
    b.有参构造方法
    成员方法
    getXxx();
    setXxx();
    给成员变量赋值的方法
    a.无参构造方法+setXxx();
    b.有参构造方法直接创建

    七.一个对象的初始化过程

    ​ 要理解Java程序初始化顺序,就得理解虚拟机从加载、编译、运行一个类的过程:
    Java程序初始化的执行顺序:

    先父后子

    ​ 父类静态代码域—>子类静态代码域—>(此时main方法开始执行)父类非静态变量—>父类非静态代码块—>父类构造方法—>子类非静态变量—>子类非静态代码块—>子类构造方法

    注意:不会自动调用静态方法!

    静态代码域

    包括静态变量、静态代码块,这些是随着虚拟机加载得时候就要执行得,且只会执行一次,它们之间得优先级是同等的,根据出现的先后来决定次序。

    非静态代码域:

    先变量,后方法,最后才是构造方法
    当运行一个子类程序时,JVM首先会先完成类的加载先父类再子类,所以会先执行父类和子类的静态代码域。加载完成后,开始编译执行(走main方法入口):main方法的代码是要new一个子类,所以首先会去初始化父类再去初始化构造子类。而初始化父类的操作是,先是非静态代码块/变量,最后是构造函数。完成了父类的创建后,按照相同的规则去构造子类。

    注意事项:

    一旦一个类被载入JVM中,同一个类就不会被再次载入了

    八.Static关键字

    是啥?

    Static是静态的意思

    有啥用?

    可以修饰成员变量成员方法,被修饰的成员会有如下特性:

    • 随着类的加载而加载,被类所有
    • 优先于对象存在,这个类的所有对象的这个static属性都相同
    • 被类的所有对象共享,即只要静态变量改变,所有对象的此变量值都发生变化
    • 这也是我们判断是否使用静态关键字的条件
    • 可以通过类名调用也可以通过对象名调用(推荐用类名调用,语义明确)
    • static类型的属性存储在方法区里的静态区

    注意事项:

    1.在静态方法中是没有this关键字的(因为this表示调用方法的对象,静态优先于对象,而且不一定有对象,可以通过类名直接访问)
    2.静态方法只能访问静态的成员变量和静态的成员方法。加载类时,不会自动调用静态方法只会被加载进方法区
    3.静态方法最好把构造方法私有化,这样就无法创建对象了,直接用类名访问
    4.当变量是静态时,一个对象的静态属性改变,属于该类的所有对象静态属性都会变化
    5.静态方法表面上可以被重写,但是实际上方法内容还是父类的内容,所以可以理解为:静态方法不能被重写

    静态变量和成员变量的区别
    1.所属不同:
    a.静态变量属于类,所以也称为为类变量
    b.成员变量属于对象,所以也称为实例变量(对象变量)

    2.内存中位置不同
    a.静态变量存储于方法区的静态区
    b.成员变量存储于堆内存

    3.内存出现时间不同:
    a.静态变量随着类的加载而加载,随着类的消失而消失
    b.成员变量随着对象的创建而存在,随着对象的消失而消失

    4.调用不同:
    a.静态变量可以通过类名调用,也可以通过对象调用
    b.成员变量只能通过对象名调用

    九.代码块

    是什么?

    (1)定义

    在Java中,用{}括起来的代码称为代码块,根据其位置和声明的不同可以
    分为四类
    (2)分类:
    A: 局部代码块
    在方法中出现,限定变量的生命周期,及早释放内存空间,提高利
    用率,离开括号就消失。

    B: 构造代码块
    在类中方法外出现,将构造方法的最前面的相同内容抽取出来,放在构造代码块中,用
    于给对象进行初始化。每次创建对象(调用构造方法)都会执行,并且在构造方法前执行.

    其实只是一个语言糖,反编译后可以发现,构造代码块里的语句会被放到每个构造方法的最前面。

    C: 静态代码块
    1.在类中方法外出现,加上static修饰符
    2.给类进行初始化,优先于main方法和构造代码块执行
    3.随着类的加载而执行的,只执行一次,
    优先级最高(相对于其他块)

    D: 同步代码块

    十.继承

    是什么?

    在Java中,类的继承是指在一个现有类的基础上去构建一个新的类。多个类中存在相同的属性和方法时,可以将这些内容抽取到单独一个类中,这样的话多个类无需再定义这些属性和方法,只需要继承那个类即可获得。

    注:实际上子类会自动拥有父类所有非private修饰的属性和方法,包括静态属性及方法经过反射的学习,可以知道其实private私有属性和方法也被隐式继承了,只是不能直接使用。

    怎么实现?

    class 子类名 extends 父类名 {}
    

    有啥用?
    1.提高了代码的复用性:
    多个类相同的成员可以放到同一个类中
    2.提高了代码的维护性:
    如果功能相同的的代码需要修改,修改一处即可
    3.让类与类之间产生了关系,是多态的前提:
    其实这也是继承的一个弊端类的耦合性很强打破了封装性

    有啥特点?

    • 单继承
    • 多层继承

    注意事项:

    • 子类能继承父类所有非私有的成员,包括静态的(成员方法和成员变量)
    • 子类不能继承父类的构造方法,但是可以通过super关键字去访问父类构造
      方法。(至于为什么,我觉得因为在子类得构造方法中隐式调用了super.()父类的无参构造被访问,所以不需要再继承了。)
    • 继承要慎重,子类 is a 父类? 否则别继承。

    子类与父类成员变量的关系

    1.子类会继承父类的非私有成员变量

    2.子类的成员变量名称和父类中的成员变量名称不同时,都可以正常调用

    3.如果子类中出现了和父类同名的成员变量,那么子类中的从父类继承来
    的变量会被隐藏,会输出子类中变量的值,但可以通过super.变量名 调用父
    类成员变量

    从jvm内存中看,如果子类父类都有同名的成员变量,父类的成员变量在子类对象的父类成员信息区中存储,而子类的成员变量,在父类成员信息区外,在对象的内存中有独立的一块空间。当对象.成员变量时候,编译器会优先检索子类成员变量,找到了就返回。(补充没有就继续到父类成员信息区中找)

    4.同样,如果子类中的方法的局部变量与子类的成员变量同名,那么成员变量也会被隐藏,会输出方法中的局部变量。 但可以通过this.变量名 调用成员变量都被隐藏在内存中的分别以this和super标识的空间中,可以调用。

    从jvm内存中看,当调用方法时候,方法栈帧进栈,此时方法内的局部变量是被优先检索到的。(若没找到,再到类中成员变量中找)

    总结:

    在子类方法中访问一个变量(就近原则)

    1.首先在子类局部范围找

    2.然后在子类成员范围找 (this)
    3.最后在父类成员范围找(肯定不能访问到父类局部范围) (super)
    4.如果还是没有就报错。

    static方法是类方法,不能访问非static成员方法

    类加载:一个自定义的类,在第一次使用的时候需要jvm加载到内存中的方法区。从class文件到jvm虚拟机内存上,就叫内加载。

    子类与父类静态成员变量的关系

    1.名字不同的静态变量可以被子类正常继承;

    在jvm中,父类先加载,静态变量声明,子类再加载,子类加载时候,继承了父类的静态变量

    2.如果子类中存在和父类名字相同的静态static变量,那么子类从父类继承来的static变量会被覆盖,具体参照内存图。

    在jvm中,父类先加载,静态变量声明,子类再加载,子类加载时候,继承了父类的静态变量. 如果自己也有同名的静态变量,就会覆盖。

    super与this关键字

    1.super可以在子类中 调用父类中名称相同的 成员方法和成员变量
    2.this可以在方法中调用 类中的与方法内局部变量名称相同 的成员方法和
    成员变量

    3.super和this的区别
    (a).this 代表当前类的对象,代表对象的内存空间标识(用来存储当前类定义的内容,成员变
    量、方法)

    (b).super (代表父类对象) 可以这么理解,实际并不代表父类对象代表对象的内存空间的标识(用来存储父类定义的内容,成员变量、方法)

    使用场景:

    当局部变量和成员变量名字相同时用this,子类变量和父类变量名字相同时用super

    子类与父类构造方法的关系

    (1).子类中所有的构造方法执行时都会默认先访问父类中无参构造方法

    (2).子类不会继承父类的构造方法

    为什么?
    a.因为子类会继承父类中的成员变量,可能还会使用父类的数据。所
    以,子类初始化之前,
    一定要先完成父类的初始化。 但是不会创建父类
    的对象。先把父类加载进内存,再把子类加载进来
    b.每一个构造方法的第一条语句默认都是隐藏的:super()
    c.并且构造方法只能调用一次别的构造方法

    通过super(参数)调用父类的构造方法,来为子类的构造方法赋值

    如果父类中没有无参构造方法该怎么办呢?

    1.显式调用父类的有参构造方法 super(参数)

    2.通过this()调用子类的其他构造方法,其他构造方法内需要用
    super(参数)显示调用父类的有参构造方法。

    注意:

    1.无论如何,子类的所有构造方法,直接或间接必须调用到父类构造方法;
    2.super() 或 this()必须是构造方法中的第一条语句,没有
    的话默认是super();

    子类与父类成员方法的关系

    1.子类会继承父类的非私有成员方法
    2.子类的成员方法和父类中的成员方法签名不同时,都可以正常调用

    3.子类的成员方法和父类中的成员方法签名相同时,如何访问方法呢?

    结论:
    通过子类对象去访问一个方法:就近原则
    1.首先在子类中找;
    2.然后在父类中找;
    3.如果还是没有就报错。

    使用特点:
    1.如果方法名不同,就正常调用方法

    2.如果方法名相同,最终使用的是子类自己的,但是可以通过super.方法名
    ()调动父类的同名方法。

    方法重写

    A.子类中出现了和父类中一模一样(名字+参数列表)的方法声明,也被称为方法覆盖,方法复写。
    1.子类的返回值类型要被父类兼容(即类型相同,或者是父类的返回值类型的子类)
    2.子类的访问权限不能比父类低,如果父类是public,子类低于它,就会报错
    B.要注意和方法重载的区别:方法重载是在同一个类中,方法名一样,参数
    列表不一样,与返回值类型无关。

    C.重写的方法前要用 @Override 来标注

    注意事项

    1.重写的方法前要用 @Override 来标注

    2.父类中私有方法不能被重写
    3.子类重写父类方法时,访问权限不能比父类更低
    4.父类静态方法,子类也必须通过静态方法进行重写。(其实这个算不上方
    法重写,但是现象确实如此,至于为什么算不上方法重写,多态中会讲解)

    应用场景:

    当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容。

    Final关键字

    • 修饰类:这类没有儿子

    • 修饰成员变量:不能再被实例改变,类中也不能二次赋值

      在类中通过,构造方法,直接赋值,构造代码块可以改变。

      必须但只能被赋值一次。new的时候

    • 修饰静态成员变量:

      类加载的时候就就通过直接赋值语句,或者静态代码块已经完成初始化。

    • 修饰局部变量,或者形参列表

      方法内只能被赋值一次

    • 修饰引用

      不可被再次修改

    • 修饰方法:方法不能被儿子重写

      修饰类的时候,实例变量起始没有被修饰

    十一.多态

    是什么?

    同一个事物,在不同时刻表现出来的不同状态。

    怎么用?

    • 有继承关系
    • 有方法重写
      重写的方法前面最好用 @Override 来标注
    • 有父类引用指向子类对象

    多态的成员访问特点

    A.成员变量/静态变量/静态方法
    编译看左边,运行看左边

    如 A a =new B() a.number; 编译要看A类里有没有number这个
    变量,运行也要调用A类里的number变量

    B.成员方法
    编译看左边,运行看右边

    如 A a =new B() a.show ; 编译要看A里有没有show方法,运行
    要执行B类里的show方法;

    有啥用?

    a.提高了程序的维护性(由继承保证)
    b.提高了程序的扩展性(由多态保证)

    多态的弊端

    A.不能访问子类特有功能,否则会编译失败报错
    B.那么我们如何才能访问子类的特有功能呢?

    答:通过多态中的转型,向下转型,强制类型转换把变量转为子类的类型。

    多态中的转型(重要)

    1.向上转型(这是Java的默认支持功能)
    a.从子类到父类
    b.父类引用指向子类对象

    2.向下转型()

    只能自己的父类引用转自己,引用的原地址指向没有变,变得只是引用的数据类型。

    十二.抽象(abstract)

    是什么:

    一些上层次的方法,具体实现应该是子类完成。上层只是应该做抽象的声明。

    例子:Person类吃饭的吃方法,不能直接实现为“正常的吃饭”, 不同国家吃的东西不一样呀。所以只声明该方法,比直接让所有子类都继承这个默认方法更好。

    关键词:abstract

    抽象类

    存在意义:为了继承而生

    特点:

    • 抽象类中可以有具体方法,也可以有抽象方法

      具体方法:给子类提供一个默认实现,提高代码复用性
      抽象方法:给出一个标准,具体子类实现这个标准

    • 不可实例化

    • abstract class 类名 {}

    • 抽象类的子类

      A.如果是抽象类:可以重写抽象方法,也可以不重写;

      B.如果不是抽象类,是具体类:必须重写抽象类中的所有抽象方法

    • 构造方法交给子类调用

    抽象方法

    • 具体子类必须重写
    • 抽象子类可以不充写
    • 没有方法体

    注意事项:

    1.private 冲突
    因为abstract是抽象的,存在的意义就是被子类继承,如果
    设置成private就不能被继承,失去了意义。
    2.final 冲突
    final修饰的方法不能被重写,也失去了继承的意义。
    3.static 无意义
    静态的方法被类所有,可以直接通过类名调用,不需要子类
    继承创建对象再去调用,没有意义。
    所以abstract只能和pulic、protected共存。

    补充:

    • 抽象类是由普通构造方法的。是给子类用的。
    • 设计抽象类,因为上层类太抽象,共性提取
    • 抽象类可以继承普通类

    十三.接口

    是什么?

    功能的集合

    怎么用?

    • [public] interface 接口名 {}
    • 类实现接口用implements表示
    • 类可以多实现接口
    • 类可以在继承的同时实现接口
    • 接口不能实例化,没有构造方法
    • 接口可以多继承接口
    • 子类implements 接口,子类就是实现类

    接口成员特点:

    成员变量:

    都是常量 默认自带public static final

    并且不支持静态代码块初始化

    成员方法

    在这之前JDK8以前都是默认抽象方法

    jdk8以后有默认方法和静态方法

    默认方法作用:还是作为一个子类的默认实现

    为了偷懒,当一个接口有多个实现类的时候,不用一个个全部强制重写了。自由决定是否重写。

    静态方法作用:

    接口名.静态方法,只有接口直接可以用

    接口主要作为一种规范,尽量不要写默认方法。直接弄一个新的接口。

    注:成员变量和成员方法都是公共的

    十四.抽象类与接口区别

    1.成员区别
    a.抽象类
    成员变量:常量或变量都可以
    构造方法:有
    成员方法:可以有普通方法,也可以有抽象方法
    b.接口
    成员变量:静态常量,默认修饰符为pulic static final
    构造方法:没有
    成员方法:默认是抽象方法,修饰符为public abstract,JDK8
    以后也可以用default和static修饰方法
    2.关系区别
    类与类 继承,只能单继承
    类与接口 实现,可单实现,可多实现
    接口与接口 继承,可单继承,可多继承
    3.设计理念区别
    抽象类 被继承体现的是:
    ”is a”的关系。共性功能
    接口 被实现体现的是:
    ”like a”的关系。扩展功能

    十五.内部类

    非静态成员内部类

    依附于外围类存在

    成员特点:

    1. 成员变量

      • 不能静态变量

      • static final 修饰的常量 倒是可以。

        只要加了final 成员变量就和常量池有关,和类加载无关了。

      • 普通成员没问题

    2. 成员方法

      • 不能静态方法
      • 普通成员没问题
    3. 构造器:

      • 和普通类并无区别,也有都是为给普通成员赋值

    原因:基于类加载的问题。只有创建了内部类的对象才会触发类加载

    外围类,内部类和外部类之间访问特点:

    内部类->外围类:
    • 成员变量无条件访问
    • 成员方法也无条件访问
    外围类->内部类:

    访问的核心在于要新建外围类对象后,再通过内部类对象区访问。

    设计目的:

    普通方法中访问:

    • 成员变量:只要新建了内部类对象就可以随便访问

    在静态方法中访问:

    • 由于是静态,外围类不一定存在,所以要创建外围类对象以及内部类对象,再去实现访问。
    外部类->内部类:

    外部类访问内部类受到访问权限限制。

    访问方法:

    外围类类名.内部类类名 引用 = new 外围类类名().new .内部类类名()

    访问静态成员

    外围类类名.内部类类名.成员

    同名问题:(就近原则)

    访问外围类成员:外围类名.this.成员

    访问内部类成员:this.成员

    访问局部变量:变量名

    总结:

    牛刀小试

    试着说一说下述访问,在成员内部类的情况下,能否进行,怎么进行

    • 内部类的成员方法中,去访问外围类的成员(普通或静态、私有成员)

      • 外围类对像的引用:外围类类名.this
    • 内部类的成员方法中,去访问外部类的成员(普通或静态、私有成员)

      • 能,创建外部类对象,受控制
    • 外围类的普通成员方法,访问内部类的成员(普通和全局常量、私有成员)

      • 不能直接访问,创建内部类对象,对象名点,不受访问权限控制
    • 外围类的静态成员方法,访问内部类的成员(普通和全局常量、私有成员)

      • 要创建两个对象,先创建外围类对象,再创建内部类对象,对象名点访问,不受访问权限控制
    • 外部类的普通成员方法,访问内部类的成员(普通和全局常量、私有成员)

      • 能访问,受内部类的访问权限控制

      • 创建两个对象,首先外围类对象,内部类对象

      • 语法

        外围类类名.内部类类名 对象名 = new 外围类名().new 内部类类名();
        
      • 通过对象名去访问,受访问权限控制

    • 外部类的静态成员方法,访问内部类的成员(普通和全局常量、私有成员)

      • 能访问,受访问权限控制
      • 创建两个对象,首先外围类对象,内部类对象
      • 通过对象名访问

    静态成员内部类(嵌套类)

    核心: 独立于外围类,但关系(访问权限)还是很亲密

    静态内部类创建的时候,可能没有外部类

    成员特点:

    成员变量: 静态,普通,final常量都可以

    成员方法:静态,普通都行。

    构造方法:也是和普通类一样

    成员变量:可以是静态成员,也可以不是静态成员

    外围类,内部类和外部类之间访问特点:

    静态内部类-> 外围类

    成员变量:

    • 普通的不能访问(要访问创对象)
    • 静态的可以,
    • 不受访问权限控制

    成员方法:

    • 成员变量的访问特点一样
    外围类->静态内部类

    在普通方法中访问:

    要创建内部类对象。

    在静态方法中访问。

    也要创建内部类对象

    外部类->静态内部类
    • 外围类类名.静态内部类类名 = new 外围类类名.静态内部类类名()
    • 受访问权限控制
    • 访问静态成员,直接 外围类类名.静态内部类类名.成员调用

    静态内部类->外部类

    一般访问方法

    例子:

    package Day12;
    
    import com.sun.org.apache.xalan.internal.xsltc.compiler.util.VoidType;
    
    import javax.print.attribute.standard.MediaSize;
    
    /**
     * @author :XiongZhikang
     * @date :Created in 2021/1/12 13:47
     * @description:
     * @modified By:
     */
    public class StaticOutSideClazz {
        int outera;
        private int outerb;
        static int outerc;
        final int outerd = 1;
        static final int outere = 2;
    
        // 外部类方法:
        private void privateOutsideShow1(){ }
        private static void staticOutsideShow2(){ }
        public void publicOutsideShow3(){ }
    
        static class Iner{
            int inera;
            private int inerb;
            static int inerc;
            final int inerd = 1;
    
    
    
    
            public void innerToOutside(){
                // 测试内->外成员变量的访问特点
                // 测试能够访问外围类的普通成员变量:无法直接访问:
    //            outera = 1  Non-static field 'outera' cannot be referenced from a static context
                // 测试能够访问外围类的静态成员变量:直接访问:
                outerc = 2; // 能够访问
                // 测试能否访问外部类的final常量
    //            outerd = 1; Non-static field 'outerd' cannot be referenced from a static context
                // 测试能否访问外部类的静态final常量 没有问题
                System.out.println(outere);
    
                // 创建外围类对象以后,外围类的成员成员都可以访问
                StaticOutSideClazz staticOutSideClazz = new StaticOutSideClazz();
                System.out.println(staticOutSideClazz.outerb);  // 并且不受访问权限控制
    
                // 总结外围类的成员变量,只要是静态的都可以直接访问。否则要创建外围类对象。
            }
    
            public void innerToOutsideMethodTest(){
                // 测试能否访问外部类静态方法,依旧直接访问,且不受访问权限控制
                staticOutsideShow2();
                //  测试能否访问外部类普通方法 不能,依旧要新建外围类对象
    //            publicOutsideShow3();
                StaticOutSideClazz staticOutSideClazz = new StaticOutSideClazz();
                staticOutSideClazz.publicOutsideShow3();
            }
    
    
    
        }
    
    
    }
    

    局部内部类:

    成员特点:

    不可以创建静态的成员

    外围类,局部内部类和外部类之间的的访问特点:

    内部类->外围类:

    成员变量:无条件访问

    成员方法:无条件访问

    外围类->内部类:

    必须在局部内部类所在方法中创建 局部内部类对象,然后局部内部类对象去调用该类的成员

    调用方式:通过外围类对象.局部内部类所在方法。去间接访问局部内部类

    局部内部类对象和局部变量的生命周期冲突

    为了解决冲突,局部内部类对象通过jvm拿到了局部变量的拷贝,由于对象很有可能修改这份拷贝,导致和局部变量值不等。所以java开发者直接默认final修饰。

    匿名内部类:

    前提:

    存在一个类或者接口
    这里的类可以是具体类也可以是抽象类。

    格式:

    new 类名或者接口名() {重写方法;}
    比如A a = new A(){
    重写方法
    } ; //注意这个分号
    

    本质:
    是一个继承了类或者实现了接口的子类匿名对象,但是实际上不需要创建子类

    talk is cheap,write and optimize my code。
  • 相关阅读:
    Swift 设置navigation左右两侧按钮
    Tab Bar Controller和Navigation Controller混合使用详细教程
    导航栏控制器和标签栏控制器(UINavigationController和UITabBarController)混用
    UIViewController、UINavigationController与UITabBarController的整合使用
    iOS开发UI篇—UIWindow简单介绍
    mod_wsgi + pymssql通路SQL Server座
    UVA 11464 Even Parity(递归枚举)
    iOS kvc
    数据的同步为每个站点创建触发器同步表
    精彩编码 【进制转换】
  • 原文地址:https://www.cnblogs.com/xiongzk/p/14267829.html
Copyright © 2011-2022 走看看