第2章 Java编程基础——FAQ2.03 用public. protected和private修饰方法有什么区别?
FAQ2.03 用public. protected和private修饰方法有什么区别?
答:
这个问题是初学者经常迷糊的地方,为了能够讲的更加清楚一些,我把Google出来的信息总结一下吧。。
下面是06年CSDN上的一份帖子精华:
————————————————————————————————————————————————————————————————————————————————————————
public 关键字修饰资源,可以在任何地方访问
protected 关键字修饰资源,可以在类内部和其子类内访问
private 关键字修饰符,只能在类内访问
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
补充一下:
还有一个包的权限,也就是什么也不写,看看下面第三个
private int a;
protected int b;
int c;
public int d;
指的是同一个包里面的其他类可以访问,出了包就不能访问了。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
分为四种:
public:表示访问权限不限;
protected:表示能被其子类和在相同包中的类访问;
默认:在相同包中被其它类访问,但包外的子类不能直接继承(包内的子类可以访问);
private:只能在类内部访问。
特别声明,默认就是默认,没有关键字,不等同于其他任何一种。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Java语言定义了Public、protected、private、abstract、static和final这6个常用修饰符
此外还定义了5个不太常用的修饰符,下面是对这11个修饰符的介绍:
1.public
使用对象:类、接口、成员
介绍:无论它所处在的包定义在哪,该类(接口、成员)都是可以访问的。
2.private
使用对象:成员
介绍:成员只可以在定义它的类中被访问
3.static
使用对象:类、方法、字段、初始化函数
介绍:命名为static的内部类是一个顶级类,它和包含类的成员是不相关的。静态方法是类方法,是被指向到所属的类,而不是类的实例。静态字段是类字段,无论该字段所在的类创建了多少实例,该字段只存在一个实例被指向到所属的类,初始化函数是在装载类时执行的,而不是在创建实例时执行的。
4.final
使用对象:类、方法、字段、变量
介绍:被定义为final的类不允许出现子类,不能被覆盖(不应用于动态查询),字段值不允许被修改。
5.abstract
使用对象:类、接口、方法
介绍:类中包含没有被实现的方法,不能被实例化。如果是一个abstract方法,则方法体为空,该方法的实现在子类中被定义,并且包含一个abstract方法的类必须是一个abstract类。
6.protected
使用对象:成员、
介绍:成员只能在定义它的包中被访问,如果在其他包中被访问,则实现这个方法的类必须是该成员所属类的子类。
7.native
使用对象:成员
介绍:与操作平台相关,定义时并不定义其方法,方法的实现被一个外部的库实现。
8.strictfp
使用对象:类、方法
介绍:strictfp修饰的类中所有的方法都隐藏了strictfp修饰词,方法执行的所有浮点
计算遵守
IEEE 754标准,所有取值包括中间的结果都必须表示为float或double类型,而不能利用
由本地平台浮
点格式或硬件提供的额外精度或表示范围。
9.synchronized
使用对象:方法
介绍:对于一个静态的方法,在执行之前jvm把它所在的类锁定;对于一个非静态类的方
法,执行
前把某个特定对象实例锁定。
10.volatile
使用对象:字段
介绍:因为异步线程可以访问字段,所以有些优化操作是一定不能作用在字段上的。
volatile有时
可以代替synchronized。
11.transient
使用对象:字段
介绍:字段不是对象持久状态的一部分,不应该把字段和对象一起串起。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public,protected,private是Java里用来定义成员的访问权限的,另外还有一种是“default”,也就是在成员前不加任何权限修饰符。如:
public class A{
void method(){};
}
method就属于default权限。
这四个修饰符的访问权限如下表:
-----------------------------------------------
类内部 package内 子类 其他
public 允许 允许 允许 允许
protected 允许 允许 允许 不允许
default 允许 允许 不允许 不允许
private 允许 不允许 不允许 不允许
-----------------------------------------------
比如:用protected修饰的成员(变量或方法),在类内部可以调用,同一个package下的其他类也可以调用,子类里也可以调用,其他地方则不可以调用,也就是说在其他package下,并且不是子类的类里,不能代用protected修饰的成员。
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public 是名字 谁都能用
protected 是门钥匙 家人能用
default 是存折 夫妻能用
private 是日记 自己能用
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
————————————————————————————————————————————————————————————————————————————————————————
关键字: class权限
首先声明:java中,friendly这个修饰符并没有显式的声明,在成员变量和方法前什么修饰符也不用,默认的就是friendly。
为了条理清晰,分三种不同情况来总结。
一 访问权限修饰符修饰成员变量和方法
public:表明该成员变量和方法是共有的,能在任何情况下被访问。
protected:必须在同一包中才能被访问。(说的比较简单,看个例子就明白了)
eg:
- class A
- {
- protected int weight ;
- protected int f( int a,int b )
- {
- // 方法体
- }
- }
class A { protected int weight ; protected int f( int a,int b ) { // 方法体 } }
假设B与A在同一个包中,则
- class B
- {
- void g()
- {
- A a=new A();
- A.weight=100;//合法
- A.f(3,4); //合法
- }
- }
class B { void g() { A a=new A(); A.weight=100;//合法 A.f(3,4); //合法 } }
特别说明:什么是在同一个包中?
答:用package打包在一起的class ,叫在同一个包中。(不明白,举个例子)
eg:在JDK的src\java\io中,你会看到许多java类,第一句源代码都是package java.io;
没有使用package打包的,在同一目录下的类也会被视做同一个包。
friendly:在这种情况下中,同protected。区别在第二和第三种情况中。
eg:
- class A
- {
- int weight ;
- int f( int a,int b )
- {
- // 方法体
- }
- }
class A { int weight ; int f( int a,int b ) { // 方法体 } }
假设B与A在同一个包中,则
- class B
- {
- void g()
- {
- A a=new A();
- A.weight=100;//合法
- A.f(3,4); //合法
- }
- }
class B { void g() { A a=new A(); A.weight=100;//合法 A.f(3,4); //合法 } }
private: 只能在本类中访问。
eg:
- class Test
- {
- private int money;
- Test()
- {
- money=2000;
- }
- private int getMoney()
- {
- return money;
- }
- public static void main(String args[])
- {
- Test te=new Test();
- te.money=3000; //合法
- int m=te.getMoney(); //合法
- System.out.println("money="+m);
- }
- }
class Test { private int money; Test() { money=2000; } private int getMoney() { return money; } public static void main(String args[]) { Test te=new Test(); te.money=3000; //合法 int m=te.getMoney(); //合法 System.out.println("money="+m); } }
PS:实际上,把重要的数据修饰为private,然后写一个public的函数访问它,正好体现了OOP的封装特性,是OOP安全性的体现。
二 访问权限修饰符修饰类
1,不能用protected和private修饰类。
2,用friendly修饰的类叫友好类,在另外一个类中使用友好类创建对象时,要保证它们在同一包中。
三 访问权限修饰符与继承
这里的访问修饰符指的是修饰成员变量和方法。可以分为两种情况:
1,子类与父类在同一包中
此时只有声明为private的变量与方法不能被继承(访问)。
eg:
- class Father
- {
- private int money ;
- int weight=100;
- }
class Father { private int money ; int weight=100; }
- class Son extends Father
- {
- viod f()
- {
- money=10000;// 非法
- weight=100; // 合法
- }
class Son extends Father { viod f() { money=10000;// 非法 weight=100; // 合法 }
2,子类与父类不在同一包中
此时private与friendly均不能被继承(访问), protected与public可以,protected的一个说法就是希望不是同一个包的类想调用它就必须通过继承来调用,否则不能。
eg:
Father.java
- package com.aaa;
- public class Father
- {
- int height ;
- protected int money=120;
- public int weight;
- protected int getMoney()
- {
- return money;
- }
- void setMoney(int newMoney)
- {
- money=newMoney;
- }
- }
package com.aaa; public class Father { int height ; protected int money=120; public int weight; protected int getMoney() { return money; } void setMoney(int newMoney) { money=newMoney; } }
Son.java
- package com.bbb;
- import com.aaa.Father;
- public class Son extends Father
- {
- void f()
- {
- money=10000;//合法
- //height=170;//非法,height为friendly修饰的变量
- System.out.println(money);//输出结果是10000
- //setMoney(300); //非法
- int number=getMoney(); //合法
- System.out.println(number);//输出结果是10000
- }
- public static void main(String args[])
- {
- Son sss=new Son();
- sss.f();
- }
- }
package com.bbb; import com.aaa.Father; public class Son extends Father { void f() { money=10000;//合法 //height=170;//非法,height为friendly修饰的变量 System.out.println(money);//输出结果是10000 //setMoney(300); //非法 int number=getMoney(); //合法 System.out.println(number);//输出结果是10000 } public static void main(String args[]) { Son sss=new Son(); sss.f(); } }
所以,访问权限修饰符权限从高到低排列是public ,protected ,friendly, private。