java与c++的访问权限的问题

时间:2021-03-14 14:58:29

转自网络:http://blog.sina.com.cn/s/blog_4bc954d30100wtxe.html

权限的理解重要理解什么是可见什么是不可见

首先声明:java中,friendly这个修饰符并没有显式的声明,在成员变量和方法前什么修饰符也不用,默认的就是friendly。

java作用域public ,private ,protected 及不写时的区别    
在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class可以认为他们都是自己的子女,而对于和自己一个目录下的class,认为都是自己的朋友。
1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有财产神圣不可侵犯嘛,即便是子女,朋友,都不可以使用。
3、protected:protected对于子女、朋友来说,就是public的,可以*使用,没有任何限制,而对于其他的外部class,protected就变成private。
作用域       当前类    同一package   子孙类     其他package

public        √       √             √           √

protected     √       √             √           ×

friendly      √       √             ×           ×

private       √       ×             ×           × 
    为了条理清晰,分三种不同情况来总结。 
   一 访问权限修饰符修饰成员变量和方法
   public:表明该成员变量和方法是共有的,能在任何情况下被访问。
   protected:必须在同一包中才能被访问。(说的比较简单,看个例子就明白了)   
       eg: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);    //合法
             }
           }
  
   friendly:在这种情况下中,同protected。区别在第二和第三种情况中。
       eg: 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);    //合法
             }
           }
    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);
                      }
                     }               
   PS: 实际上,把重要的数据修饰为private,然后写一个public的函数访问它,正好体现了OOP的封装特性,是OOP安全性的体现。

二  访问权限修饰符修饰类
   1,不能用protected和private修饰类
   2,用friendly修饰的类叫友好类,在另外一个类中使用友好类创建对象时,要保证它们在同一包中

三   访问权限修饰符与继承
   这里的访问修饰符指的是修饰成员变量和方法。可以分为两种情况:
   1,子类与父类在同一包中
    此时只有声明为private的变量与方法不能被继承(访问)。
   eg:
     class Father
     {
       private int money ;
       int weight=100;
      
      }
     class Son extends Father
     {
       viod f()
       {
         money=10000;//   非法
         weight=100; //   合法
        }
      }
    2,子类与父类不在同一包中
    此时private与friendly均不能被继承(访问), protected与public可以。
     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;
       }
      }
    
      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();
           }
       }
  所以,访问权限修饰符权限从高到低排列是public  ,protected  ,friendly, private。

C++中

由于不存在包的概念,因此,protected与java中的protected有所不同,Java中的protected不但,子对象可以访问,而且包里的其它地方,也可以显示的通过子对象调用,如

package pack1

public class A{

protected int a;

}

package pack1

public class B{

public static void main(String[] args){

System.out.println(a);

}

}

上述代码是没有问题的,但如果B与A不在同一个包中,则不能访问。因此,在java中,protected在可见性在与packaged权限类似,而只是在继承性上,没有对包划界,packaged权限不允许子象访问其它包内父对象的包访问权限的属性。

在C++里,protected属性有严格的定义,即只具有垂直的访问权限,只有其自身与其后代可以访问,限一个类的protected属性,只有其内部与子对象内部可以访问,而在其它地方是不可见的,为了说明这个问题,见以下代码:

class A{
protected:
 int a;
protected:
 void print(){
  cout<<"A protected method"<<endl;
 }
};
class B:public A{
protected:
 void test(){
  cout<<"test A"<<endl;
 }
};
int main(){
 B b;
 b.test();
 //b.print();
}

上述代码是无法编译的,因为b.test()在main里是不可见的,main无法访问b的protected方法,即使方法是通过子对象来调用的,如果把B中的protected方法改为public,则代码可以,编译成功,编译成功后,在B中可以房问父类的protected属性.

下表列出了C++三种继承对属性的访问情况:

           public继承    protected继承          private继承

public属性      public      protected                private

protected属性      protected         protected                private

private属性      不可见              不可见                      不可见