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。
  • 相关阅读:
    poj 2411 Mondriaan's Dream 骨牌铺放 状压dp
    zoj 3471 Most Powerful (有向图)最大生成树 状压dp
    poj 2280 Islands and Bridges 哈密尔顿路 状压dp
    hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp
    poj 3311 Hie with the Pie 经过所有点(可重)的最短路径 floyd + 状压dp
    poj 1185 炮兵阵地 状压dp
    poj 3254 Corn Fields 状压dp入门
    loj 6278 6279 数列分块入门 2 3
    VIM记事——大小写转换
    DKIM支持样本上传做检测的网站
  • 原文地址:https://www.cnblogs.com/xiongzk/p/14267829.html
Copyright © 2011-2022 走看看