zoukankan      html  css  js  c++  java
  • 成员变量的定义与使用

    成员变量的定义与使用


         成员变量又称为成员属性,它是描述对象状态的数据,是类中很重要的组成成分。本节详细讨论如何来定义成员变量、成员变量的访问权限,以及静态成员变量与实例成员变量之间的区别。


     成员变量的定义


        定义成员变量的语法如下:
    [变量修饰符] 类型说明符变量名
    类的成员变量和在方法中所声明的局部变量都是用户标识符,它们的命名规则相同。变量修饰符是可选项,一个没有变量修饰符的变量定义如下:

    public class Cuber{
    double width,height;
    int number;
    }
    

      


    成员变量的类型可以是Java中的任意数据类型,包括基本类型、数组、类和接口。在一个类中,成员变量应该是唯一的,但是成员变量的名字可以和类中某个方法的名字相同,例如:

    public class Point{
    int x, y;
    int x(){
    return x;
    }
    }
    

      


    其中,方法x()和变量x具有相同的名字,但笔者不赞成这样写,因为这会引起不必要的混淆。
    可以用成员变量修饰符来规定变量的相关属性,这些属性包括:
    ● 成员变量的访问权限。一共有4种访问权限可供选择,在3.3.2节将详细介绍。
    ● 成员变量是否为静态。默认情况下,成员变量是实例成员,在外部需要通过对象才能操作。如果用static修饰,就成为了静态成员,也称为类变量,无需通过对象就可以操作。
    ● 是否为常量。默认的是变量,如果前面加上final关键字,它就是一个常量。
    这些修饰符可以任意组合使用。加上修饰符的成员变量如下所示:

    public class Cuber{
    private double width,height; //定义两个私有的成员变量
    public static int count; //定义一个公共的静态类变量
    public static final int COLORE=1; //定义一个公共的整型静态常量
    }
    

      


    虽然Java并没有规定,成员变量必须定义在类的开始部分,不过在实际编程中,多数程序员将成员变量定义在成员方法的前面。
    3.3.2 成员变量的访问权限
    访问权限修饰符声明了成员变量的访问权限。Java提供的显示的访问权限修饰符有3种,分别是:私有(private)、保护(protected)和公共(public)。除此之外,还有一种默认的访问权限:friendly,它并不是Java的关键字,只有当变量前面没有写明任何访问权限修饰符时,就默认以friendly作为访问权限。为了表达上的方便,省略了其中“成员”两字,将被这些修饰符所修饰的变量分别称为私有变量、保护变量和公共变量。下面分别讨论各个修饰符的用法。
    1.公共变量
    凡是被public修饰的成员变量,都称为公共变量,它可以被任何类所访问。即允许该变量所属的类中所有方法访问,也允许其他类在外部访问。如例3.2所示。
    【例3.2】 公共变量使用示例。

    //-----------文件名declarePublic.java,程序编号3.2------------------
    public class declarePublic{
    public int publicVar=10; //定义一个公共变量
    }



      


    在类declarePublic中声明了一个公共变量publicVar,它可以被任何类所访问。下面这段程序中,类otherClass可以合法地修改变量publicVar的值,而无论otherClass位于什么地方。

    1 //-----------文件名otherClass.java,程序编号3.3------------------
    2 public class otherClass{
    3 void change(){
    4 declarePublic ca=new declarePublic(); //创建一个declarePublic对象
    5 ca.publicVar=20; //通过对象名来访问它的公共变量,正确
    6 }
    7 }
    View Code


    用public修饰的变量,允许任何类在外部直接访问,这破坏了封装的原则,造成数据安全性能下降,所以除非有特别的需要,否则不要使用这种方案。
    2.私有变量
    凡是被private修饰的成员变量,都称为私有变量。它只允许在本类的内部访问,任何外部类都不能访问它。
    【例3.3】 私有变量使用示例。

    1 //-----------文件名declarePrivate.java,程序编号3.4------------------
    2 public class declarePrivate{
    3 private int privateVar=10; //定义一个私有变量
    4 void change(){
    5 privateVar=20; //在本类中访问私有变量,合法
    6 }
    7 }
    View Code


    如果企图在类的外部访问私有变量,编译器将会报错。

    1 //-----------文件名otherClass.java,程序编号3.5------------------
    2 public class otherClass{
    3 void change(){
    4 declarePrivate ca=new declarePrivate(); //创建一个declarePrivate对象
    5 ca.privateVar=20; //企图访问私有变量,非法
    6 }
    7 }
    View Code


    为了让外部用户能够访问某些私有变量,通常类的设计者会提供一些方法给外部调用,这些方法被称为访问接口。下面是一个改写过的declarePrivate类。

     1 //-----------文件名declarePrivate.java,程序编号3.6------------------
     2 public class declarePrivate{
     3 private int privateVar=10; //定义一个私有变量
     4 void change(){
     5 privateVar=20;
     6 }
     7 public int getPrivateVar(){ //定义一个接口,返回私有变量privateVar的值
     8 return privateVar;
     9 }
    10 public boolean setPrivateVar(int value){ //定义一个接口,可以设置privateVar
    11 的值
    12 //可以在这里先检测value是否在允许的范围内,然后再执行下面的语句。
    13 privateVar = value;
    14 return true;
    15 }
    16 }
    View Code


    私有变量很好地贯彻了封装原则,所有的私有变量都只能通过程序员设计的接口来访问,任何外部使用者都无法直接访问它,所以具有很高的安全性。但是,在下面这两种情况下,需要使用Java另外提供的两种访问类型:
    ● 通过接口访问私有变量,将降低程序的性能,在程序性能比较重要的情况下,需要在安全性和效率间取得一个平衡。
    ● 私有变量无法被子类继承,当子类必须继承成员变量时,需要使用其他的访问类型。
    3.保护变量
    凡是被protected修饰的变量,都被称为保护变量。除了允许在本类的内部访问之外,还允许它的子类以及同一个包中的其他类访问。子类是指从该类派生出来的类。包是Java中用于管理类的一种松散的集合。二者的详细情况将在第4章介绍。下面是一个简单的 例子。
    【例3.4】 保护变量使用示例。
    下面这个程序先定义一个名为onlyDemo的包,declarProtected类就属于这个包。

    1 //-----------文件名declareProtected.java,程序编号3.7------------------
    2 package onlyDemo;
    3 public class declareProtected{
    4 protected int protectedVar=10; //定义一个保护变量
    5 void change(){
    6 protectedVar=20; //合法
    7 }
    8 }
    View Code


    %说明:读者编译这个文件时,需要用这个命令(下同):
    javac -d . 文件名
    下面这个otherClass类也定义在onlyDemo包中,与declareProtected类同属于一个包。

    1 //-----------文件名otherClass.java,程序编号3.8------------------
    2 package onlyDemo;
    3 public class otherClass{ //它也在包onlyDemo中
    4 void change(){
    5 declareProtected ca=new declareProtected();
    6 ca.protectedVar=20; //合法
    7 }
    8 }
    View Code


    下面这个deriveClass类是declareProtected的子类,它并不在onlyDemo包中。它也可以访问保护变量protectedVar,但是只能通过继承的方式访问。

    1 //-----------文件名declareProtected.java,程序编号3.9------------------
    2 import onlyDemo.declareProtected; //引入需要的包
    3 public class deriveClass extends declareProtected{ //定义一个子类
    4 void change(){
    5 //合法,改变的是deriveClass从declarProtected中所继承的protectedVar值
    6 protectedVar=30;
    7 }
    8 }
    View Code


    %说明:import是Java中的关键字,用于引入某个包。这将在4.13节中详细介绍。
    子类如果不在父类的同一包中,是无法通过“对象名.变量名”的方式来访问protected类型的成员变量,比如下面这种访问是非法的:

    1 //-----------文件名deriveClass.java,程序编号3.10-----------------
    2 import onlyDemo.declareProtected;
    3 public class deriveClass extends declareProtected{ //定义一个子类
    4 void change(){
    5 declareProtected ca=new declareProtected();
    6 ca.protectedVar=30; //错误,不允许访问不在同一包中的保护变量
    7 }
    8 }
    View Code


    4.默认访问变量
    如果在变量前不加任何访问权修饰符,它就具有默认的访问控制特性,也称为friendly变量。它和保护变量非常像,它只允许在同一个包中的其他类访问,即便是子类,如果和父类不在同一包中,也不能继承默认变量(这是默认访问变量和保护变量的唯一区别)。因为它限定了访问权限只能在包中,所以也有人称默认访问权限为包访问权限。
    【例3.5】 默认访问变量使用示例。

     1 //-----------文件名declareDefault.java,程序编号3.11------------------
     2 package onlyDemo; //本类定义在包中
     3 public class declareDefault{
     4 int defaultVar=10; //定义一个默认访问变量
     5 void change(){
     6 defaultVar=20; //合法
     7 }
     8 }
     9 onlyDemo包中的其他类,可以访问defaultVar变量:
    10 //-----------文件名otherClass.java,程序编号3.12------------------
    11 package onlyDemo;
    12 public class otherClass{ //它也在包onlyDemo中
    13 void change(){
    14 declareDefault ca=new declareDefault();
    15 ca.defaultVar=20; //合法
    16 }
    17 }
    View Code


    下面是它的子类,也在onlyDemo包中。它除了可以像包中其他类那样通过“对象名.变量名”来访问默认变量,还可以通过继承的方式来访问。

     1 //-----------文件名deriveClass.java,程序编号3.13------------------
     2 package onlyDemo;
     3 public class deriveClass extends declareDefault{ //定义一个子类
     4 void change(){
     5 //合法,改变的是deriveClass从declarDefault中所继承的defaultVar值
     6 defaultVar=30;
     7 }
     8 }
     9 如果子类不在onlyDemo包中,就不会继承默认变量,也就无法像上面那样来访问。
    10 //-----------文件名deriveClass.java,程序编号3.14------------------
    11 import onlyDemo.declareDefault;
    12 public class deriveClass extends declareDefault{ //定义一个子类
    13 void change(){
    14 defaultVar=30; //非法,这个变量没有继承下来
    15 }
    16 }
    View Code


    3.3.3 实例成员变量和静态成员变量
    1.实例成员变量
    在3.3.2节中,所有的对象都是实例成员变量。它们的最大特色是:如果所属的对象没有被创建,它们也就不存在。如果在类的外部使用它,需要先创建一个对象,然后通过“对象名.变量名”来访问。前面所有的例子都遵循了这一规则。在类的内部,实例成员方法也可以直接访问实例成员变量,比如例3.5,具体原因,将在3.5节中讲述。
    不同的对象,拥有不同的实例成员变量,它们互不干扰。
    【例3.6】 不同对象的实例成员变量使用示例。

     1 //-----------文件名instanceVar.java,程序编号3.15------------------
     2 public class instanceVar{
     3 protected int instVar=0; //定义一个实例成员变量
     4 }
     5 下面这个类showInstVar用两个对象来访问它的实例成员变量。
     6 //-----------文件名showInstVar.java,程序编号3.16------------------
     7 public class showInstVar{
     8 public static void main(String args[]){
     9 instanceVar one = new instanceVar(); //创建对象one
    10 instanceVar two = new instanceVar(); //创建对象two
    11 //分别为这两个对象的成员变量赋值
    12 one.instVar = 100;
    13 two.instVar = 200;
    14 //分别显示这两个对象的成员变量值
    15 System.out.println("one.instVar="+one.instVar);
    16 System.out.println("two.instVar="+two.instVar);
    17 }
    18 }
    View Code


    程序3.16输出的结果如下:
    one.instVar=100
    two.instVar=200
    从本例中明显地看出,不同对象的成员变量是不相同的,它们互不干涉。
    2.静态成员变量
    在某些情况下,程序员希望定义一个成员变量,可以独立于类的任何对象,即所有的对象都共用同一个成员变量。由于Java中不能像C一样定义全局变量,因此,Java中引入了静态成员变量。
    在成员变量前加上static标识符就可以定义一个静态成员变量。相对于实例成员变量,静态成员变量具有以下特点:
    ● 它被类的所有对象共享,因此又被称为类变量。
    ● 它不是属于某个具体对象,也不是保存在某个对象的内存区域中,而是保存在类的公共存储单元。因此,可以在类的对象被创建之前就能使用。
    ● 它既可以通过“对象名.变量名”方式访问,也可以通过“类名.变量名”的方式访问。它们是完全等价的。
    【例3.7】 静态成员变量使用示例。

     1 //-----------文件名staticVar.java,程序编号3.17------------------
     2 public class staticVar{
     3 protected static int stat=0; //定义一个静态成员变量
     4 }
     5 下面这个程序使用不同的方法来访问这个静态变量。
     6 //-----------文件名showStaticVar.java,程序编号3.18------------------
     7 public class showStaticVar{
     8 public static void main(String args[]){
     9 staticVar.stat=100; //通过类名.变量名访问静态变量,无需创建对象
    10 System.out.println("staticVar.stat="+staticVar.stat);
    11 staticVar one = new staticVar(); //创建对象one
    12 staticVar two = new staticVar(); //创建对象two
    13 //分别为这两个对象的静态成员变量赋值
    14 one.stat = 200;
    15 two.stat = 300;
    16 //分别显示这两个对象的静态成员变量值
    17 System.out.println("one.stat="+one.stat);
    18 System.out.println("two.stat="+two.stat);
    19 //再通过类来显示静态变量的值
    20 System.out.println("staticVar.stat="+staticVar.stat);
    21 }
    22 }
    View Code


    程序3.18输出结果如下:
    staticVar.stat=100
    one.stat=300
    two.stat=300
    staticVar.stat=300
    从上述结果中可以看到,静态变量stat是一个公共变量,无论哪个对象改变了它的值,对其他所有该类对象都有效。静态变量的一个重要作用是当作同类各个对象之间传递信息使用,类似于C语言中的全局变量。但这样破坏了数据的封装原则,往往会留下隐患,所以使用这类变量时需要万分谨慎。
    静态变量的另一个用途是定义静态常量,比如:
    public static double PI = 3.1415926;
    这样的静态常量可以无需创建对象就直接使用,省略了创建对象的步骤,类似于C语言中用define定义的常量。这样定义常量,不仅使用方便,而且节省内存空间。在JDK中,存在着大量的这种静态常量。
    %说明:本节中所有的成员变量的类型都是基本类型,其实它们也都可以是复合类型,比如数组、类、接口等类型。

  • 相关阅读:
    VS2010 自动跳过代码现象
    Reverse Linked List II 【纠结逆序!!!】
    Intersection of Two Linked Lists
    Linked List Cycle II
    Remove Nth Node From End of List 【另一个技巧,指针的指针】
    Swap Nodes in Pairs
    Merge Two Sorted Lists
    Remove Duplicates from Sorted List
    Linked List Cycle
    Dungeon Game
  • 原文地址:https://www.cnblogs.com/meixinyuan/p/4827680.html
Copyright © 2011-2022 走看看