1.权限
在Java中提供了四种访问权限,使⽤不同的访问权限修饰符修饰时,被修饰的内容会有不同的访问权限:
- public:公共的
- protected:受保护的
- default(friendly):默认的,一般不加这个关键词
- private:私有的
不同权限的访问能力
2.封装(private)
为了代码跟数据的安全性,防止其他类随意访问本类的信息,就考虑到封装这个方法。
封装步骤:
- 使用private关键字来修饰成员变量
- 对需要访问的成员变量,提供对应的一对get();/set();方法
上面说到private是最小权限,它能修饰成员变量跟成员方法,被它修饰后,只能在本类中访问。
封装优化:1.this.关键字 2.构造方法 ——>详细见文章 java day05
权限、封装代码说明
//关于权限
/*
* 1.public
* 2.protected
* 3.default
* 4.private
* */
public class Qx {
public int n_public = 1;
protected int n_protected = 2;
int n_default = 3;
private int n_private = 4;
//封装获得方法
public int getN_private(){
return n_private;
}
//封装获得方法
public void setN_private(int n_private){
this.n_private = n_private;
}
//给不同包下的子类使用
public int getN_default(){
return n_default;
}
public void setN_default(int n_default) {
this.n_default = n_default;
}
//给不同包没有关系的类使用
public int getN_protected() {
return n_protected;
}
public void setN_protected(int n_protected) {
this.n_protected = n_protected;
}
//成员方法
public void s1(){
System.out.println(n_public);
System.out.println(n_protected);
System.out.println(n_default);
System.out.println(n_private);
}
}
//这里是同包 没有关系的类
public class Test01 {
public static void main(String[] args) {
Qx qx = new Qx();
System.out.println(qx.n_public);
System.out.println(qx.n_protected);
System.out.println(qx.n_default);
//访问不到private私有的成员变量,它只能在它所在的类里被访问
qx.s1(); //1 2 3 4 //但好像能调用含private的成员方法
//在没有封装get,set方法前,私有变量是访问不了的,之后通过这两个方法就能访问了
System.out.println(qx.getN_private());//获得私有成员变量4
qx.setN_private(8);//修改私有成员变量
System.out.println(qx.getN_private());//8被修改了
qx.s1();//1 2 3 8
}
}
//同包,继承Qx的子类
public class Test02 extends Qx {
public static void main(String[] args) {
Qx qx = new Qx();
System.out.println(qx.n_public);
System.out.println(qx.n_protected);
System.out.println(qx.n_default);
qx.s1();
qx.setN_private(6);
qx.getN_private();
}
}
import day07.a_publictest.Qx;
//这里是不同包下,继承Qx子类调用测试
public class Test03 extends Qx {
public void m3(){
System.out.println(n_public);
System.out.println(n_protected);
//只能访问上面两种类型的成员变量
getN_default();
getN_private();
}
}
import day07.a_publictest.Qx;
//不同包,也没有关系的类
public class Test04 {
public static void main(String[] args) {
Qx qx = new Qx();
System.out.println(qx.n_public);
//只能访问到公开成员变量
qx.getN_private();
qx.getN_default();
qx.getN_protected();
}
}
3.JavaBean
JavaBean是Java语言编写的一种标准规范,符合标准规范的类,要求类必须是具体的和公共的,并且具有无参数的构造方法,提供用来操作成员变量的set和get方法。
public class
ClassName
{
//
成员变量
//
构造⽅法
//
⽆参构造⽅法【必须】
//
有参构造⽅法【建议】
//
成员⽅法
// getXxx()
// setXxx()
}
4.static关键字(静态的)
static可以修饰:成员变量,成员方法,代码块,内部类
1.定义
类变量:使用static关键词修饰的成员变量 :static 数据类型 变量名;
类方法(静态方法):使用static关键字修饰的成员方法
修饰符
static
返回值类型
⽅法名
(
参数列表
) {
//
执⾏语句
}
2.调用
//
访问类变量 属于类
类名
.
类变量名
;
//
调⽤静态⽅法
类名
.
静态⽅法名
(
参数
);
注意:
1.静态⽅法可以直接访问类变量和静态⽅法。
2.静态⽅法
不能直接访问
普通成员变量或成员⽅法。反之,成员⽅法可以直接访问类变量
或静态⽅法。
3.静态⽅法中,不能使⽤
this关键字。
静态⽅法只能访问静态成员。
代码说明
public class Main01 {
public static void main(String[] args) {
Demo01 d = new Demo01();
//用对象.变量名/方法名 只能调用普通成员变量跟普通成员方法 属于对象
d.name = "luck";
d.m1();//luck0
//用类名.变量名/方法名 就能调用静态成员变量跟静态成员方法 属于类
Demo01.age = 12;
Demo01.m2();//12
//下面在给静态成员变量赋值后再一次调用普通成员方法,就有一样的值了
d.m1();//luck12
}
}
//关于静态static修饰词
/*
* 1.静态成员变量
* 2.静态成员方法
* */
public class Demo01 {
//普通成员变量
String name;
//静态成员变量
static int age;
//构造方法
Demo01(){
}
Demo01(String name){
this.name=name;
Demo01.age=age;//因为是静态成员变量不能用this关键字只能 类名.变量名
m2();
}
//普通成员方法
public void m1(){
//在普通成员方法里可以调用静态成员变量跟静态成员方法
m2();
System.out.println(name + age);
}
//静态成员方法
public static void m2(){
//m1();//编译报错 说明在静态成员方法里不能调用普通成员方法
//System.out.println(name);//编译报错 说明在静态成员方法里不能调用普通成员变量
System.out.println(age);
}
}
3.静态内存图
4.静态代码块
- 代码块:
1.执行在构造方法之前
2.作用:给成员变量初始化,提取所有构造方法中重复的代码 - 静态代码块:1.在类加载时执行:a.实例化对象 b.使用静态方法 c.使用静态变量 2.作用: 优化代码,提升程序效率 3.静态代码块可以有无数个,但只进行一次性的加载,只有一个 4.在静态代码块中不能调用非静态成员变量。
静态代码块和静态变量的执行顺序:先写那个先执行那个
注意: 静态变量先执行,是可以进行运算操作
静态代码块先执行,是不可以进行运算操作,因为变量未定义,所以一般先定义静态变量
代码说明
public class Main02 {
public static void main(String[] args) {
Demo02 demo02 = new Demo02();//1.执行静态代码块(只会执行一次)2.执行代码块3.执行无参构造
demo02.a = 5;
}
}
//代码块
//静态代码块
//执行顺序
public class Demo02 {
//成员变量
int a;
static int b;//静态成员变量
//静态代码块
static {
System.out.println("执行父类静态代码块");
}
//代码块
{
System.out.println("执行父类代码块");
}
//构造方法
Demo02(){
System.out.println("执行父类无参构造");
}
Demo02(int a){
System.out.println(a+"执行父类有参构造");
}
父子类代码块执行顺序: 父类静态代码块 -> 子类静态代码块 -> 父类代码块 -> 父类构造方法 -> 子类代码块 -> 子类构造方法
代码说明
//父类子类代码块执行顺序
public class Main03 {
public static void main(String[] args) {
Demo03 demo03 = new Demo03();
/*1.执行父类静态代码块
2.执行子类静态代码块
3.执行父类代码块
4.执行父类无参构造
5.执行子类代码块
6.执行子类无参构造*/
}
}
//代码块父子类执行顺序
public class Demo03 extends Demo02{
int b;
//静态代码块
static {
System.out.println("执行子类静态代码块");
}
//代码块
{
System.out.println("执行子类代码块");
}
//构造方法
Demo03(){
System.out.println("执行子类无参构造");
}
Demo03(int b){
System.out.println(b+"执行子类有参构造");
}
}
5.final关键字(最后的,不可被改变的)
可以修饰:类,成员变量,局部变量,成员方法
类:被修饰的类,不能被继承。
⽅法:被修饰的⽅法,继承后,不能被重写。
变量:被修饰的变量,不能被重新赋值。
基本数据类型:值不可被修改
引用数据类型:地址值不可被修改,但其对应对象的内容可被修改
代码说明
1.基本数据类型
//final关键词
// //final修饰基本数据类型
public class Demo01 {
public static void main(String[] args) {
//final修饰基本数据类型
int a = 10;
System.out.println(a);//10
a = 20;
System.out.println(a);//20 普通变量能被重新赋值
final int b = 10;//final修饰的int类型值就不可变了
// b = 30;//编译报错 因为被final修饰了
final int c;
c = 30;//这样赋值是可以被允许的
// c = 40;//当第二次赋值就不行了
}
}
2.引用数据类型
import java.util.Arrays;
//final修饰的引用数据类型
//数组
public class Demo02 {
public static void main(String[] args) {
//普通数组
int[] arr = new int[]{11,22,5};
arr = new int[]{55,22};//可以被重新修改内容,长度等
//final修饰的数组
final int[] brr = new int[]{22,55,4};
System.out.println(Arrays.toString(brr));//[22, 55, 4]
System.out.println(brr);//地址值[I@50cbc42f
//brr = new int[]{1,2,3};不被允许
brr[0] = 2;//但里面的元素可以被改变
System.out.println(Arrays.toString(brr));//[2, 55, 4]
System.out.println(brr);//[I@50cbc42f
//所以数组不可变的是他的地址值
}
}
3.final父子类继承对象
//final修饰的对象
public class Demo03 {
public static void main(String[] args) {
final Student stu = new Student();
stu.age = 5;
stu.name = "lucy";
//成员变量可以重新赋值
// stu = new Student();不允许 因为地址值改变了
Student stu1 = new Student();
//
stu1.f1();//fuf1111
stu1.f2();//fuf222
ZiStudent ziStu = new ZiStudent();
ziStu.f1();//被重写的f1
//fuf1111
//6666
}
}
public class Student {
int age;
String name;
//final int id;//-->这样的编码会报错,因为成员变量自己有初始值,如果用了final修饰就必须给他初始化
final int id = 123456;
public void f1(){
System.out.println("fuf1111");
}
//final修饰的成员方法也不能被继承的子类重写
public final void f2(){
System.out.println("fuf222");
}
}
public class ZiStudent extends Student{
@Override//父类普通成员方法重写
public void f1() {
super.f1();
System.out.println("6666");
}
//final修饰的成员方法也不能被继承的子类重写
// public final void f2() {
//super.f1();
// }
}