Skip to content

Latest commit

 

History

History
408 lines (354 loc) · 9.97 KB

javaBasic3.md

File metadata and controls

408 lines (354 loc) · 9.97 KB

####局部变量和全局变量(成员变量)的区别:

局部变量:随着方法入栈而初始化,方法出栈而消失
			没有默认值,必须声明后赋值
			保存在栈中
			作用域为声明的位置到它所在的结构结束

成员变量:随着初始化对象而创建,会随着对象的回收而消失
		有默认值的
		保存在堆中
		作用域在整个类中
注意:当局部变量和成员变量重名时,局部变量会覆盖全局变量

####访问修饰符: private:私有的,只有当前类的内部可以访问 [default]:默认的,可以在同一个包中访问 protected:受保护的,可以在同一个包中或者不同包的子类中可以访问 public:公有的,所有类均可以访问

this:当前对象。当出现局部变量和成员变量重名时需要通过this来访问成员变量

####构造方法 构造方法:方法名和类名相同个,没有返回值类型 作用:初始化成员变量 调用:new 注意:如果没有显示声明构造方法,系统会提供默认无参构造方法. 如果显示声明构造方法,系统不提供默认构造方法。 类名(){ }

类名(参数){
	初始化数据成员
}

this():可以表示当前构造函数,必须位于代码行的第一行

####static关键字: 1 静态成员变量: 特点: 1) 和类同时加载,会在方法去开辟空间,初始化数据 2) 通过类名访问。 类名.静态成员变量 3) 通常用于存储所有类的共享数据

2 静态成员方法:
特点:
1)静态方法中只能访问静态成员(不能使用this)
2)非静态方法中可以访问静态成员也可以访问非静态成员

静态成员变量和非静态成员变量区别:
1)生命周期
	静态成员变量随着类的加载而加载,在方法区初始化,在程序结束即消失
	非静态成员变量随着对象的初始化,在堆中创建,在对象被垃圾回收时而消失

2)存储
	静态成员变量通常保存对象共享的数据
	非静态成员变量是保存某一个对象的数据

3)访问方式
	静态成员变量通过类名直接访问,也可以通过对象访问
	非静态成员变量只能通过对象访问
class  Student
{
	static String sex = "男";  //静态成员变量

	private int age;  //实例成员变量

	public void setAge(int age){
		this.age = age;
	}

	//静态方法
	public static void setSex(String sex){
		Student.sex = sex;
		//age = 15;  //静态方法中不能访问非静态变量
		/*Student s = new Student();  //在静态方法中如果想访问实例成员,需要通过对象访问
		s.age = 15;*/
	}
	//实例方法
	public void show(){
		setSex("女");
		System.out.println(sex+"   "+ age);
	}
}

####代码块

构造代码块:优先于构造方法执行,主要用于初始化成员变量
			每次创建对象都会执行
静态代码块:static{},用来初始化静态成员变量。随着类的加载而执行,只执行一次
注意:在程序优化中,不建议过多的使用static,因为它会长时间保留在内存中
class Demo06 
{
public static void main(String[] args) 
	{
		System.out.println("main方法开始执行.....");
		{
			//普通代码块:作用域
			int i= 6;
			System.out.println("i-->"+i);
		}//i作用域消失
		int i = 10;
		System.out.println("iiii-->"+i);

		
		System.out.println("*****************");
		Student s1 = new Student();
		System.out.println("*****************");
		new Student();	
	}
	static int num = 10;
	int a = 5;
	//静态代码块
	static{
		System.out.println("静态代码块1");
		System.out.println(num);
		//System.out.println(a);  //静态代码块中不能直接引用非静态成员
	}
	static{
	System.out.println("静态代码块2");
	}

	/*如果执行该代码块程序将强制退出
	static{
		System.exit(-1);
	}*/
}


class Student
{
	static  int age = 1;

	{
		System.out.println("构造代码块1");
	}
	{
		System.out.println("构造代码块2");
	}
	public Student(){
		System.out.println("Student构造方法");
	}
	{
		System.out.println("构造代码块3");
	}
}

程序运行结果

静态代码块1
    10
静态代码块2
main方法开始执行.
i-->6
iiii-->10
*****************
构造代码块1
构造代码块2
构造代码块3
Student构造方法
*****************
构造代码块1
构造代码块2
构造代码块3
Student构造方法

这里再看一个例子:

package Demo;

/**
 * Created by wswenyue 
 */
public class Test1 {
public static void main(String[] args) {
System.out.println("------------new 子类-------------");
new B().f();
System.out.println("----------new 父类--------------");
new A().f();
}
}

class A {
public int a ;
static {
System.out.println("父类静态代码块1");
}
public A(){
System.out.println("父类无参构造方法");
}
public A(int a){
this.a = a;
System.out.println("父类有参参构造方法");
}

public void f(){
{
System.out.println("父类方法--普通代码块");
}
System.out.println("父类方法");
}

{
System.out.println("父类普通代码块");
}
static {
System.out.println("父类静态代码块2");
}
}

class B extends A {
public int a ;
static {
System.out.println("子类静态代码块1");
}
public B(){
System.out.println("子类无参构造方法");
}
public B(int a){
this.a = a;
System.out.println("子类有参参构造方法");
}

public void f(){
{
System.out.println("子类方法--普通代码块");
}
System.out.println("子类方法");
}

{
System.out.println("子类普通代码块");
}
static {
System.out.println("子类静态代码块2");
}
}

执行结果:

------------new 子类-------------
父类静态代码块1
父类静态代码块2
子类静态代码块1
子类静态代码块2
父类普通代码块
父类无参构造方法
子类普通代码块
子类无参构造方法
子类方法--普通代码块
子类方法
----------new 父类--------------
父类普通代码块
父类无参构造方法
父类方法--普通代码块
父类方法

####对象初始化过程: 1 加载类的字节码文件到jvm的方法区中 2 为静态变量在静态区开辟内存空间,赋初始值 3 加载静态代码块,初始化静态成员变量 4 开辟堆中空间(成员变量),给成员变量初始化 5 加载构造代码块 6 加载构造方法 7 将堆空间的首地址赋值给栈中对象的引用

示例:

class Demo07 
{
	public static int age;
	static{  //静态代码块
		System.out.println("静态代码块");
		System.out.println("age--->"+age);
		age = 18; //初始化静态成员变量,在类加载的时候执行
		System.out.println("age--->"+age);
	}
	{
		System.out.println("构造代码块");
		//构造代码块
		age += 1;
		System.out.println("age--->"+age);
	}
	Demo07(){
		System.out.println("构造方法");
	}
	public static void main(String[] args) 
	{
		new Demo07();
		new Demo07();
		new Demo07();
	}
}

运行结果

静态代码块
age--->0
age--->18
构造代码块
age--->19
构造方法
构造代码块
age--->20
构造方法
构造代码块
age--->21
构造方法

####继承 子类可以继承父类非私有的成员 继承的传递性:---多层继承 class A{} class B extends A{} class C extends B{}

#####子类对象初始化过程: 1 父类静态代码块 2 子类静态代码块 3 父类构造代码块 4 父类构造方法 5 子类构造代码块 6 子类构造方法 示例

//父类对象
class Parent
{
	private String name;
	public int age;
	static{
		System.out.println("父类的静态代码块");
	}
	{
		System.out.println("父类的构造代码块");
	}
	Parent(){
		System.out.println("父类的构造方法");
	}
	public void say(){
		System.out.println("父类age:"+age);
	}
}

//子类对象
class Child extends Parent
{
	private int age;
	static{
		System.out.println("子类静态代码块");
	}
	{
		System.out.println("子类构造代码块");
	}
	Child(){
		System.out.println("子类构造方法");
	}
	public void sayHi(){
		super.age = 100;
		this.age = 50;
		System.out.println("子类age:"+age);
		say();
	}
	
//现在我们来调用测试一下
public static void main(String[] args) 
{
	Child c = new Child();
	c.sayHi();
}

输出结果:

父类的静态代码块
子类静态代码块
父类的构造代码块
父类的构造方法
子类构造代码块
子类构造方法
子类age:50
父类age:100

this和super:

this:代表当前对象。this.成员。
	   this()本类的构造方法,必须在第一行
super:代表父类对象,并不是一个引用,没有父类的指向(因此super不能作为参数传递)
		可以通过super.父类成员来访问父类的成员
		也可以通过super()调用父类的构造方法,必须在第一行
	
this()和super()不能同时出现
this和super关键字不能出现在静态方法中

#####重写(覆盖) 前提条件 必须继承 注意: 1 父类的私有方法不能被重写 2 子类重写父类的方法时,重写的方法权限必须大于等于父类中的方法权限 3 静态只能静态覆盖 4 当父类中的方法有返回类型时,子类重写父类方法时,返回类型可以是父类类型也可以是父类的子类类型