测试Java的访问修饰符
访问修饰符
public protected default(即不写也不能写) private
父类
package com.keke.myself.test01;
/**
* @ClassName: Person
* @Description:
* @Author: keke
* @Date: 2021/4/9
*/
public class Person {
//成员变量 :new一个本类对象才能调用
public int a = 1;
protected int b = 2;
int c = 3;
private int d = 4;
//类变量 :通过类名直接调用
public static int e = 5;
protected static int f = 6;
static int g = 7;
private static int h = 8;
//构造方法
public Person() {
}
protected Person(int a) {
this.a = a;
}
Person(int a, int b) {
this.a = a;
this.b = b;
}
private Person(int a, int b, int c, int d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
//成员方法 / 非静态方法 :new一个本类对象才能调用
public void a() {
System.out.println("aaa");
}
protected void b() {
System.out.println("bbb");
}
void c() {
System.out.println("ccc");
}
private void d() {
System.out.println("ddd");
}
//静态方法 :通过类名直接调用
public static void e() {
System.out.println("eee");
}
protected static void f() {
System.out.println("fff");
}
static void g() {
System.out.println("ggg");
}
private static void h() {
System.out.println("hhh");
}
}
同一个包下的子类
package com.keke.myself.test01;
import com.keke.myself.test02.Student;
/**
* @ClassName: Teacher
* @Description:
* @Author: keke
* @Date: 2021/4/9
*/
public class Teacher extends Person {
public Teacher() {
// super(1,2,3,4); //报错
// super(1,2);
// super(1); //覆盖默认的无参构造方法,不能写多个父类的构造方法
// super(); //不写默认也调用父类的无参构造方法
}
public static void main(String[] args) {
Person p = new Person();
int a = p.a;
int b = p.b;
int c = p.c;
// int d = p.d; //报错
int e = Person.e;
int f = Person.f;
int g = Person.g;
// int h = Person.h; //报错
p.a();
p.b();
p.c();
// p.d(); //报错
Person.e();
Person.f();
Person.g();
// Person.h(); //报错
Person p1 = new Person(1);
Person p2 = new Person(1, 2);
// Person p2 = new Person(1, 2, 3, 4); //报错
Teacher teacher = new Teacher();
int ta = teacher.a;
int tb = teacher.b;
int tc = teacher.c;
// int td = teacher.d; //报错
teacher.a();
teacher.b();
teacher.c();
// teacher.d(); //报错
// super(); //Call to 'super()' must be first statement in constructor body:构造方法只能写在子类构造方法的第一行
Student student = new Student();
//满足同包非子类,故protected修饰的可以访问
//不满足同包子类(子类指new出来的对象所代表的类与创建对象的类相同且都是子类),故default修饰的不能访问
int sa = student.a;
int sb = student.b;
// int sc = student.c; //报错
// int sd = student.d; //报错
student.a();
student.b();
// student.c(); //报错
// student.d(); //报错
}
}
同一个包下非子类
package com.keke.myself.test01;
import com.keke.myself.test02.Student;
/**
* @ClassName: Animal
* @Description:
* @Author: keke
* @Date: 2021/4/9
*/
public class Animal {
public Animal() {
// super(); //不是子类不能使用super关键字调用父类的构造方法,此super调用的是Object类的构造方法
}
public static void main(String[] args) {
Person p = new Person();
int a = p.a;
int b = p.b;
int c = p.c;
// int d = p.d; //报错
int e = Person.e;
int f = Person.f;
int g = Person.g;
// int h = Person.h; //报错
p.a();
p.b();
p.c();
// p.d(); //报错
Person.e();
Person.f();
Person.g();
// Person.h(); //报错
Person p1 = new Person(1);
Person p2 = new Person(1, 2);
// Person p2 = new Person(1, 2, 3, 4); //报错
Teacher teacher = new Teacher();
int ta = teacher.a;
int tb = teacher.b;
int tc = teacher.c;
// int td = teacher.d; //报错
teacher.a();
teacher.b();
teacher.c();
// teacher.d(); //报错
// super(); //Call to 'super()' must be first statement in constructor body:构造方法只能写在子类构造方法的第一行
Student student = new Student();
//满足同包非子类(相对于创建对象与父类)故protected修饰的可以访问
//不满足同包子类(创建对象的类是子类),故default修饰的不能访问
int sa = student.a;
int sb = student.b;
// int sc = student.c; //报错
// int sd = student.d; //报错
student.a();
student.b();
// student.c(); //报错
// student.d(); //报错
}
}
不同一个包下的子类
package com.keke.myself.test02;
import com.keke.myself.test01.Person;
import com.keke.myself.test01.Teacher;
/**
* @ClassName: Student
* @Description:
* @Author: keke
* @Date: 2021/4/9
*/
public class Student extends Person {
public Student() {
// super(1,2,3,4); //报错
// super(1,2); //报错
// super(1); //覆盖默认的无参构造方法,不能写多个父类的构造方法
// super(); //不写默认也调用父类的无参构造方法
}
public static void main(String[] args) {
Person p = new Person();
int a = p.a;
// int b = p.b; //报错
// int c = p.c; //报错
// int d = p.d; //报错
int e = Person.e;
int f = Person.f;
// int g = Person.g; //报错
// int h = Person.h; //报错
p.a();
// p.b(); //报错
// p.c(); //报错
// p.d(); //报错
Person.e();
Person.f();
// Person.g(); //报错
// Person.h(); //报错
// Person p1 = new Person(1);
// Person p2 = new Person(1, 2);
// Person p2 = new Person(1, 2, 3, 4); //报错
Student student = new Student();
int sa = student.a;
int sb = student.b;
// int sc = student.c; //报错
// int sd = student.d; //报错
student.a();
student.b();
// student.c(); //报错
// student.d(); //报错
Teacher teacher = new Teacher();
//不满足不同包子类(子类指new出来的对象所代表的类与创建对象的类相同且都是子类)
int ta = teacher.a;
// int tb = teacher.b; //报错
// int tc = teacher.c; //报错
// int td = teacher.d; //报错
teacher.a();
// teacher.b(); //报错
// teacher.c(); //报错
// teacher.d(); //报错
}
}
不同一个包下不是子类
package com.keke.myself.test02;
import com.keke.myself.test01.Person;
/**
* @ClassName: Plant
* @Description:
* @Author: keke
* @Date: 2021/4/9
*/
public class Plant {
public Plant() {
// super(); //不是子类不能使用super关键字调用父类的构造方法,此super调用的是Object类的构造方法
}
public static void main(String[] args) {
Person p = new Person();
int a = p.a;
// int b = p.b; //报错
// int c = p.c; //报错
// int d = p.d; //报错
int e = Person.e;
// int f = Person.f; //报错
// int g = Person.g; //报错
// int h = Person.h; //报错
p.a();
// p.b(); //报错
// p.c(); //报错
// p.d(); //报错
Person.e();
// Person.f(); //报错
// Person.g(); //报错
// Person.h(); //报错
// Person p1 = new Person(1);
// Person p2 = new Person(1, 2);
// Person p2 = new Person(1, 2, 3, 4); //报错
Student student = new Student();
//不满足不同包子类(子类指new出来的对象所代表的类与创建对象的类相同且都是子类)
int sa = student.a;
// int sb = student.b; //报错
// int sc = student.c; //报错
// int sd = student.d; //报错
student.a();
// student.b(); //报错
// student.c(); //报错
// student.d(); //报错
}
}
结论
1、public修饰符修饰成员变量、类变量、构造方法、成员方法(即非静态方法)、静态方法在不同包及同包的子类或者其他类都能访问
2、private修饰符修饰成员变量、类变量、构造方法、成员方法(即非静态方法)、静态方法在不同包及同包的子类或者其他类都不能访问
3、protected修饰符修饰成员变量、类变量、构造方法、成员方法(即非静态方法)、静态方法在同包的子类或者其他类都能访问,不同包的子类,类变量和静态方法没问题,可以通过类名直接访问,但成员变量和成员方法new一个父类不能访问,只能通过new一个子类才能访问,构造方法不能在子类的成员方法和静态方法中访问(即子类的成员方法和静态方法不能new一个父类对象),但可以在子类的构造方法中通过super关键字访问;不同包的非子类均不能访问
4、default(即不写也不能写)修饰符修饰成员变量、类变量、构造方法、成员方法(即非静态方法)、静态方法在同包的子类或者其他类都能访问,不同包的子类和非子类均不能访问
需要注意的是:无论在不同包,还是相同包下,在子类中new一个父类对象,就相当于是在用非子类去访问,protected修饰符指的不同包下的子类和同一包下的子类及非子类的可以访问的意思:其中不同包下的子类和同一包下的子类指的是在不同包下的子类和同一包下的子类下new一个自身对象(即子类对象)可以访问,这一定义明白在相同包下无所谓,但若在不同包下的子类new一个父类不能访问,只能通过new一个子类才能访问。
记住:不同包子类:不同包指创建对象的类与父类在不同包,子类指new出来的对象所代表的类与创建对象的类相同且都是子类
同包子类:同包指创建对象的类与父类在相同包,子类指new出来的对象所代表的类与创建对象的类相同且都是子类