learn-java

变量声明

class 类名{
    //类体内容:
        //变量声明:
    	成员变量=实例变量=实例=实例成员
        static 成员变量=类变量=静态变量
            
        //方法的定义:
            实例方法=[修饰符] 类型 方法名称1(参数|也是局部变量){
                构造函数=方法名称1()
                局部变量
             }
            类方法=static 实例方法=static 类型 方法名称2(参数|也是局部变量){
                构造函数=方法名称2()
                局部变量
            }
} 

成员变量与局部变量

  成员变量 局部变量
别名 实例变量、实例、实例成员  
static修饰时 类变量、静态变量  
位置 类体中变量定义部分所定义的变量被称为类的成员变量。 在方法体中定义的变量和方法的参数被称为局部变量。
有效性 成员变量在整个类内都有效,其有效性与它在类体中书写的先后位置无关。//和方法同级 局部变量只在定义它的方法内有效
1. 参数–整个方法有效
2.方法中定义–在方法中且方法中声明位置之后有效
3.局部变量声明在复合语句中–在该复合语句内且在声明位置之后有效
默认值 成员变量在定义时有默认值 局部变量在定义时没有默认值
     
     
     
     
     

有效性–局部优先

如果局部变量的名字与成员变量的名字相同,则成员变量被隐藏,即该成员变量在这个方法内暂时失效。

如果想在该方法中使用被隐藏的成员变量,必须使用关键字this

class Tom {
   int x = 10,y;
   void f() {
         int x = 5;
         y = x+x;  
       //y得到的值是10,不是20。
      //如果方法f 中没有“int x=5;”,y的值将是20
    }
}
//------------------------------
class Tom {
    int x = 10,y;
    void f() {
       int x = 5;
       y = x+this.x;    //y得到的值是15
 }}    //this当前所在区域

public class test {
    int a = 10, b = 0;              //成员变量,在整个类中有效
    public static void main(String[] args) {
        //m = 9;                    //非法,因为m声明位置在后面,声明位置之后才有效
        int m = 10, sum = 0;        //局部变量,在函数中且在声明位置之后有效
        if (m > 9) {
            //    z = 2 * m + z;    //非法,因为z声明位置在后面,声明位置之后才有效
            int z = 10;             //z仅仅在该复合语句后面有效
            z = 2 * m + z;          //合法,局部变量,在复合语句中且在声明位置之后有效
        }
        for (int i = 0; i < m; i++) {
            sum = sum + i;          //合法,i仅仅在该循环语句中有效
        }
        m = sum;                    //合法,因为m和sum有效
        //   z = i+sum;             //非法,因为i和z已无效
    }
}

默认值

成员变量有默认值,但局部变量没有默认值,因此在使用局部变量之前,必须保证局部变量有具体的值 。

//例如:下列InitError类无法通过编译。

class InitError {
   int x = 10,y;      //y的默认值是0
    void f() {
       int m;         //m没有默认值,但编译无错误
       x = y+m;    //无法通过编译,因为在使用m之前未指定m的值
    }
} 
数据类型 实例成员 静态成员
整型(byte|short|int|long) 0 0
浮点型(float|double) 0 0
字符型(char) 空字符\u0000 空字符\u0000
布尔型( boolean) false false
引用型(类|数组|接口) null null
     
public class DefaultValue {
    // 实例成员变量
    private boolean bool;
    private byte b;
    private short s;
    private char c;
    private int i;
    private long l;
    private float f;
    private double d;
    private String str;
    private String[] strArray;
    // 静态成员变量
    private static boolean boolStatic;
    private static byte bStatic;
    private static short sStatic;
    private static char cStatic;
    private static int iStatic;
    private static long lStatic;
    private static float fStatic;
    private static double dStatic;
    private static String strStatic;
    private static String[] strArrayStatic;

    public void printInstanceField() {
        System.out.println("实例成员变量默认值:");
        System.out.println("boolean:" + bool);
        System.out.println("byte:" + b);
        System.out.println("short:" + s);
        System.out.println("char:" + c);
        System.out.println("int:" + i);
        System.out.println("long:" + l);
        System.out.println("float:" + f);
        System.out.println("double:" + d);
        System.out.println("String:" + str);
        System.out.println("String[]:" + strArray);
    }

    public static void printStaticField() {
        System.out.println("静态成员变量默认值:");
        System.out.println("boolean:" + boolStatic);
        System.out.println("byte:" + bStatic);
        System.out.println("short:" + sStatic);
        System.out.println("char:" + cStatic);
        System.out.println("int:" + iStatic);
        System.out.println("long:" + lStatic);
        System.out.println("float:" + fStatic);
        System.out.println("double:" + dStatic);
        System.out.println("String:" + strStatic);
        System.out.println("String[]:" + strArrayStatic);
    }

    public static void main(String[] args) {
        DefaultValue dv = new DefaultValue();
        dv.printInstanceField();
        dv.printStaticField();
    }
}
/*
实例成员变量默认值: 
boolean:false 
byte:0 
short:0 
char: 
int:0 
long:0 
float:0.0 
double:0.0 
String:null 
String[]:null 
静态成员变量默认值: 
boolean:false 
byte:0 
short:0 
char: 
int:0 
long:0 
float:0.0 
double:0.0 
String:null 
String[]:null
*/

public class CharDefaultValue {
    static char c;

    public static void main(String[] args) {
        System.out.println((int) c);
        System.out.println(c == '\u0000');
    }
}
/*
0 
true
*/

可以把数组的元素看作是数组的成员变量(实际上不是),当数组分配空间时,数组的元素(行为类似于成员变量)就可以获得默认的初始值。不过,对于局部变量数组本身(即value),如果没有初始化,同样没有默认值。

 public static void main(String[] args) {
        int[] value = new int[10];
        System.out.println(value[0]);
    }
//0

对象的组合与复用

一个类可以把对象作为自己的成员变量,如果用这样的类创建对象,那么该对象中就会有其它对象,也就是说该对象将其他对象作为自己的组成部分,或者说该对象是由几个对象组合而成。

如果一个对象a组合了对象b,那么对象a就可以委托对象b调用其方法,即对象a以组合的方式复用对象b的方法。通过组合对象来复用方法有以下特点。

(1)通过组合对象来复用方法也称“黑盒”复用,因为当前对象只能委托所包含的对象调用其方法,这样一来,当前对象对所包含的对象的方法的细节(算法的细节)是一无所知的。

(2)当前对象随时可以更换所包含的对象,即对象与所包含的对象属于弱耦合关系。

在学习对象的组合时,一定要记住:一个类声明的两个对象如果具有相同的引用,二者就具有完全相同的变量

如果一个类A把对象b作为自己的成员变量,用这个类A创建对象时,是不为这个b分配空间,只有一个b的null引用,需要用b对应的类Bnew一个对象b2,然后把b2引用给A,此时b和b2具有相同引用,指向相同的新建对象,这时候即时再用Bnew一个b2也不会对A的b造成影响。

class b{
    getFunb{	
        
    }
}
//-------------------
class A{
    B b;        //B是类,b是b声明的对象,类A把对象b作为自己的成员变量
    setFuna(B temp){
        b = temp;
    }
    getFuna(){
        return getFunb()*2; //getFuna()函数调用getFunb函数
    }
}
//--------------------
A a;            //类A声明了对象a,此时a的只是一个引用,其他的什么也没有
//--------------------
a = new A();    //声明的对象a分配变量,此时a成员变量已经有了默认值,a的b是引用型变量,默认值是null
//--------------------
B b1 = new B(); //B声明了一个对象b1,并为其分配变量,此时b1是一个引用,并且指向一个空间
/*(对象的本质就是变量,类数据类型和int一样,对象引用型变量,和int test 的test一样,只不过是个引用型变量,对比为数组,int test1[],test1和上面的b1一样,指向一个空间,自身是个引用变量,类似指针)*/
//--------------------
a.setFuna(b1);		//a调用a的函数,将b1的引用传给a的b,此时b1和a的b拥有相同引用,指向相同的空间,且a的b可以委托调用B的方法
//--------------------
B b1 = new B(); 	//此时对A的a没有任何影响,只是b1重新指向别的空间了
//-------------------
a.getFuna();		//a调用a的getFuna()函数,其中getFuna()函数调用getFunb函数

关联关系和依赖关系

关联关系

A中的成员变量是用B类声明的对象,那么A和B的关系是关联关系,称A类的对象关联于(或组合了)B类的对象

如下图Circular类的对象关联于(或组合了)Circle类的对象

依赖关系

参考: