Java学习笔记(1):访问修饰符protected和default的区别

访问修饰符,即对访问范围的控制。在Java中,有以下几种访问修饰符:

1.对类而言:

(1)public:在所有的包中均可见

(2)default(默认):只在该类所在包中可见

注:类不能用private和protected来修饰

2.对成员变量和成员方法而言:

(1)public:在所有包中均可见(且可调用)

(2)protected:包内所有类中均可见(且可调用),包外有继承关系的子类可见(仅可在子类内部调用)

(3)private:只在同一个类中可见(且可调用)

(4)default(默认):

注意:

在同一个包中,尽管是protected的方法和属性,包内的任何类都可以访问到。

在父类和子类不在同一个包中的前提下,对于子类来说,子类继承了父类所有的属性和方法(任何访问修饰符),虽然对从父类继承来的protected的属性和方法可见,但是只能在子类的内部进行访问,即:(this.)方法名、(this.)属性名进行访问和操作,而无法在外部对子类进行实例化,并用子类对象.protected方法或属性来访问。

举个简单的例子,我们都知道Object类是所有类的父类,而在Object中有一个叫clone()的方法,那我们在实例化对象后能调用这个函数吗?通过实践证明是不可以的,给出的错误提示是:The method clone() from the type Object is not visible.该方法是不可见的,这就类似于我们刚刚提到的,虽然子类从父类中继承过来了包括protected的方法和属性,但对于外部的类(包括main函数中)都是无法获取到的。


下面,再通过一个简单的例子来说明这个问题:

首先,在同一个项目中创建两个包test.demo1和test.demo2,然后在test.demo1包中分别创建三个类Parent、Child和Test类,并让Child类去继承Parent类,然后再test2.demo2中再去分别去创建两个Child类和Test类,这个Child类也让它继承test.demo1中的Parent类。结构如下图所示:

Java学习笔记(1):访问修饰符protected和default的区别_第1张图片

然后我们对这几个类进行一些对属性和方法的操作:

test.demo1中:

Parent类:

package test.demo;

public class Parent {
	
	protected int num = 10;

	protected void method(){
		System.out.println("父类的method方法");
	}
}
Child类:

package test.demo;

public class Child extends Parent{

}

Test类:

package test.demo;

public class Test {
	
	public static void main(String[] args) {
		Child child = new Child();
		System.out.println(child.num);
	}
}
运行Test中的main方法时没有报错,正确显示了结果:10

test.demo2中:

Child类:

package test.demo1;

import test.demo.Parent;

public class Child extends Parent{
	
	public Child(){
		method();//父类的method方法
	}
}
Test类:

package test.demo1;

import test.demo.Parent;

public class Test {

	Parent p;
	
	public void fun(){
		
	}
	public static void main(String[] args) {
		Child child = new Child();
	}
}

运行结果:显示“父类的method方法”。

由此可见,test.demo2包中Child对象继承了父类中的method方法,并在构造函数中成功调用。现在我们来对以上代码进行一些修改:

(1)我们在test.demo2中Test类的main函数中尝试获取Child对象中的num属性会报错,原因在于num的属性是protected的,无法在外部获取和调用。

(2)我们将Parent类中的num属性和method方法的protected去掉,即访问修饰符变为default.结果显示,test.demo1中的Test依然能正常运行,显示结果10,但是在test.demo2中Child类和Test类都报错了,原因是由于父类中的method方法已被修改成了default,而default的方法和属性只能在父类所在的包中被访问,所以,当Child和Parent不在同一个包中,就算是在子类内部也无法访问到默认访问修饰符的属性和方法。


你可能感兴趣的:(Java)