访问控制符
private | default | protected | public | |
---|---|---|---|---|
同一个类中 | √ | √ | √ | √ |
同一个包中 | √ | √ | √ | |
子类中 | √ | √ | ||
全局范围内 | √ |
外部类只有两种访问控制级别:public、default
:
- 类本身对在自身内部作用,所以无需private
- 类本身就对子类作用,所以protected和default一样,故无需protected
当类为default时,其内部成员还是可以使用上述4中修饰符。当外部类为default时,子类public的范围就是包。
this
- 含义: 实例方法的第一个形式参数(实际参数是调用方法的对象的地址)
所以,this在实例方法中就是当前对象的起始地址,也即this指向当前对象
当前对象存储内容包括:
1) 所有父类(直接和间接)的所有成员变量(包括私有和被覆盖的)
(只不过私有访问不了,被覆盖的在实例方法中需要用super或者类名访问)
2) 该对象所属类新增的成员变量(包括增加的和复写的) - 使用环境:
- 非静态函数 调用其所属对象成员变量或成员函数 的时候(即非静态函数 调用同类成员)//非同类成员的调用,使用的是对象名或者类名
- 为和函数中同名局部变量作区分,必须使用 this.xxx 显示表示成员变量
- 在构造函数中启动另外一个构造函数,实现对当前变量再赋值
- Java不允许直接调用构造器
- this()必须是构造器第一行语句
- 将当前执行的对象传到另一个方法中
- 注意:speak()中的System.out.println(name+":"+age); 其实是System.out.println(this.name+":"+this.age);
成员函数亦同理(因为成员函数的操作数针对特定对象,所以需要this来)
也就是说,对象的非静态函数,只要想要调用该对象的成员变量或者函数,都需要使用this进行调用,这个值就是其被调用时自动产生的this值
- 内存: 在调用其所在的非静态函数时生成,this引用存在于非静态方法区中
super
- 含义: 实例方法中,super的值就是this的值,两者的区别在于JVM在处理super的时候和this不同
JVM在处理this 的时候,把this 当成合法引用, 可以直接输出this 的值,使用this 调用方法时, 用的是多态
调用指令
处理super的时候,把super当成非法引用,不可直接输出super的值,使用super调用方法时, 用的是避免多态
调用指令 - 使用:
- 在子类中,调用父类的成员,尤其被子类覆盖了的成员
当通过super在子类中调用父类的成员函数时,父类成员函数使用的是父类的成员变量 - 在子类中,调用父类构造器
必须出现在子类构造器第一行(即不能和this()构造器同时出现)
static
- 作用
static用来修饰成员变量和成员方法以及内部类,随着类的加载而在方法区的静态方法区生成,为该类所有对象共有,且不针对任何一个对象 - 静态变量
随着类的加载而生成(已经完全成熟可用),为类的所有成员共享(只占一份内存空间)(一改全改),可以通过类名直接调用(也可以通过对象名调用,但不推荐) - 静态方法
静态方法只能直接访问本类中的静态成员
(不可以使用this和super关键字)(没有这默认参数this)
非静态方法既可以直接访问静态成员,又可以直接访问非静态成员)
原因:静态方法和静态变量在程序一加载就已经生成了,而对象要程序创建时才能生成,所以静态方法没有this参数,因而不能访问非静态成员。
- 应用
成员变量: 当类中某个变量的值,对所有对象都一样,且不需要在使用中改变时,就将其设为静态
成员函数: 当类中某个函数不需要访问非静态成员变量,则设为静态,否则,设为非静态。(该静态的时候不静态,会因为创建对象而浪费空间) - 其他
1.静态方法和静态变量前面省略的是类名
2.类引用存在于静态方法区中
3.静态函数只能覆盖静态函数
final
- final修饰的类 不可以被继承—区别不可变类
- final修饰的方法 不可以被覆盖
- final修饰的变量 不可以被修改,必须由程序员显示赋值(系统不管)
由于是常量,所以当其为成员变量时,对所有对象都一样,所以往往为节省内存,将其加上static
变量的名字需要全大写,多个单词,中间用下划线连接
赋初值位置: (有final修饰时)- 类变量: 必须在 声明时 or 静态初始化块 中赋值
- 实例变量:必须在 声明时 or 非静态初始化块 or 构造器中赋值
- 局部变量:不使用可以不赋值;若使用,则使用前赋值即可,可以声明时赋值,也可以先声明再赋值
和宏替换的关系:
final变量赋值时,若右侧没有调用方法,则编译时可确定值编译器 进行宏替换;若右侧有调用方法,则编译器不可确定值,需运行时确定,编译器不进行宏替换
abstract
- 抽象方法: 即方法的声明(注意没有方法体,和有方法体(定义)没有内容不一样)
- 抽象类: 含有抽象方法的类,需要用abstract修饰
1) 抽象类不可以被实例化–即使被实例化也没有意义,因为其对象功能不完全,而我们所需要的对象都是功能完全的
2) 抽象类的其子类必须覆盖了其所有的抽象方法后,才可以实例化,否则这个类还是抽象类
3) 抽象类必须有子类
3) 也有构造函数,用于给子类进行初始化
4) 抽象类可以不定义抽象方法–目的:不让该类创建对象,通常这个类中的方法有方法体,但是却没有内容 - abstract不能和以下关键字一起用:
1) private: 因为抽象类中的方法需要子类中方法覆盖,定义成private子类就继承不了了
2) static: static修饰成员表示类出现的时候成员就生成了(成员和类共存亡),但是抽象方法是没有完善的类,类创建的时候该方法并没有生成,所以二者不可共用
3) final: final说明不让继承,而abstract就是用来被继承的