Java 面向对象  对象创建过程 对象 属性(类变量) 构造方法 权限 初始化 继承 方法

  1. 首次创建对象时或者对象的静态方法或静态属性被首次访问,Java解释器查找类路径,定位ClassName.class文件
  2. 载入ClassName.class(创建一个对象),所有静态初始化动作执行(首次使用这些动作或属性时),并且所有静态初始化动态只在此时执行一次
  3. 当new ClassName()创建对象时,首先在堆为className对象分配足够的内存空间
  4. 相对应的内存空间清零,className对象的所有基本数据类型设置默认值,引用型设置为NULL,进行初始化
  5. 执行所有出现在字段定义处的初始化动作,例如bowl3被赋予指向Bowl3对象的引用
  6. 执行构造器

对象

  • 非内部类不能使用private或者protected修饰符
  • 数组是不能指定长度的,只能获取引用
int[] nums = new int[4];


其中 int[] nums里的[]里面不能填入数字

所谓的数组长度其实是一个误区,new int[4]开辟了一个 4*4的内存块,这里才是长度,但这是内存的长度

nums所做的只是获取这个内存的引用,即获取这块内存的位置

所以说数组是无法指定长度的
 所以下面这个数组扩充操作就很容易理解了

 通过copyOf()函数实现数组长度扩充 source=Arrays.copyOf(source,source.length+mount) 

eg:
    int[] nums = new int[4];
     
    nums = Arrays.copyOf(nums,nums.length+3);

    这里其实是创建了两个数组内存,第一次是new int[4],然后nums获取了这块内存的地址

    然后copyOf()创建了新数组内存,长度为原数组长度+3,并获取原数组的地址
    
    然后将新内存的地址重新赋值给nums



实例代码:

public class Arrays {
    public static void main(String[] args) {

	String[] strings = new String[] { "asd", "fhd", "asd", "fdk" };

	for (int i = 0; i < strings.length; i++) {

	    System.out.println(strings[i] + "的hash值:" + strings[i].hashCode());
	}

	strings = Arrays.copyOf(strings, strings.length + 1);
	strings[4] = "1243";

	System.out.println("--------------------------");

	for (int i = 0; i < strings.length; i++) {
	    System.out.println(strings[i] + "的hash值:" + strings[i].hashCode());
	}

    }
}


结果:

asd的hash值:96882
fhd的hash值:101346
asd的hash值:96882
fdk的hash值:101229
--------------------------
asd的hash值:96882
fhd的hash值:101346
asd的hash值:96882
fdk的hash值:101229
1243的hash值:1509472



结果分析:

结果符合预期,而且发现原来的string数组元素的hash值和后面的是一样的
更加说明了java所有变量都是对常量引用





属性(类变量)

  • 可以直接在定义时赋值初始化
class Test{
    public int i = 9;
}
  • 可以通过调用其他函数进行初始化
  • 类变量系统会自动赋值,甚至先于构造函数赋值
class Test{

    public int i;//系统自动赋值i=0;
    
    Test{
        i=8; //i从0重新赋值为8
    }

}
  • 属性(类变量)一定先于方法调用之前赋值,无论变量在哪定义
class Test{

    public int i;//系统自动赋值i=0;
    
    Test{
        i=8; //i从0重新赋值为8
    }

    int m = 9; //先于Test()赋值

}
  • 静态成员变量在且仅在第一次使用的时候初始化,初始化顺序为先静态变量,后静态方法,存放在方法区
  • 成员变量和局部变量的变量名可以相同
  • 变量在同名时采取的是就近原则

int i =3;

void fun(){

    int i =6;//合法
    
}








int m =3;

void f(int m){

    m = m; //m != 3,这里的两个m都是形参带来的m
    
}

构造方法

  • 构造方法是超类开始执行的

示例代码:

public class PowerOfExtrend {
	public static void main(String[] args) {
		son son = new son();
		
	}

}
class grandFather{
	public grandFather() {
		System.out.println("grandFather!");
	}
}

class father extends grandFather{
	public father() {
		System.out.println("father!");
	}
	
}

class son extends father{
	public son() {
		System.out.println("son!");
	}
}



结果:grandFather!
     father!
     son!

结果分析:在子类的构造方法内部,系统会自动在最前面添加super();来调用父类的构造方法,所以构造方法的执行是从祖先类开始的,一直到当前类


权限

Java 面向对象
 对象创建过程
对象
属性(类变量)
构造方法
权限
初始化
继承
方法

注意:为了清楚起见,应按public,protected,default,private来排列成员

  • 每个编译单元(文件)都只能有由一个public类,表示没有编译单元都由单一的公共接口(public class),如果出现超过一个,则编译器会报错
  • puiblic class 的名称必须完全和该编译单元的文件名相同,包括大小写
  • 虽然不常用,但一个编译单元是可以没有任何public类,这种情况下可以随意给编译单元命名

初始化

初始化的4中方法

  1. 在定义对象的初始化,这意味着变量将在构造器调用被初始化
  2. 在类的构造器中初始化
  3. 在使用对象之前,这种方式被称为惰性初始化,这种方式可以减小额外的负担,使用函数调用来初始化。
    *
    惰性初始化:当需要一个实例的时候才初始化一个对象。
    新建两个简单的类,第二个类中包含第一个类的一个引用,当
    需要第一个类的对象是调用Lazy()方法即可获得第一个类的对象。
    */
    class Object1{
        int i;
    }
    
    public class Object2{
     Object1 oj1 ;
     public void print(){
      if(oj1==null)
          oj1 = new Object();
     }
     public static void main(String[] args){
      Object2 object2 = new Object2();
      object2.print();
     }
    }
    
  4. 使用实例初始化

继承

Java中的继承与c++不同,java中的类的变量和方法继承后权限是不变的

示例代码:

public class PowerOfExtrend {
	public static void main(String[] args) {
		son son = new son();
		son.power();
	}

}
class grandFather{
	protected int i =18;
	protected void power(){
		System.out.println("grandGather!");
		System.out.println("i="+i);
	}
}

class father extends grandFather{
	
	
	@Override
	protected void power() {
		System.out.println("father!");
		System.out.println("i="+i);
	}
}

class son extends father{
	@Override
	protected void power() {
		System.out.println("son");
		System.out.println("i="+i);
	}
}


结果:
     son
     i=18

结果分析:
        子类father继承了父类grandFather的protected变量i和prote方法power(),
        但father的子类son还是可以访问protected变量i和prote方法power(),
        没有出现因为继承而权限缩小,而导致grandFather类的孙类son无法访问
        grandFather类相关方法和变量的问题


方法

  • 静态方法是无法使用静态方法做参数的,会出现编译错误,但可以使用静态变量作为参数

代码:

public class Customer {
	static int m =34;
	
	public static void main(String[] args) {		
		f1();
	//	f2();
	}
	
	public static int f1() {
		System.out.println(m);
		return 1;
	}

	
        /* 会报错
        public static void f2(int f1()) {
		System.out.println("1");
	}
        */

}


结果:34