static变量和成员变量的区别:
1、所属不同:静态变量属于类,所以也成为类变量;成员变量属于对象,所欲也称为实例变量(对象变量)
2、内存中位置不同:静态变量存储于方法区的静态区,成员变量存储于堆内存的中
3、内存出现时间不同:静态变量随着类的加载而加载,成员变量随着对象的创建而存在,随着对象的消失而消失
4、调用不同:静态变量可以通过类名调用,也可以通过对象调用;成员变量只能通过对象名(引用变量)调用;
package bamzhy.method; public class demo4 { static int i; public static void main(String[] args) { Student stu = new Student(); System.out.println("number="+stu.number); Student.number=20; //静态方法的性质同静态变量 Student.showNumber(); System.out.println((stu.setName()).age); } // public void test(){ // //在非静态上下文(context)不能出现static关键字 // static int i; // } //}
通过访问控制修饰符(access modifications)可以限制成员变量在类或对象外部的可见性
public 域在任何地方都可以访问;
protected 受保护的,仅在类体重、子类类体重或同包的其他类雷替中可访问;即在类中被声明为protected的域可以被同一个包中的该类的对象访问,也能被其子类访问。而不管它们是否在同一个包中。
1、类体中;
2、子类类体中(同包异包都可以);
3、同包的其他类类体;
private 私有的,域仅在类体中可访问,只有在同一类中创建的对象才能访问私有域。在其他类中创建的对象不能访问私有域。
(如果不写)默认的package,没有任何访问修饰符的域
1、仅在类体中
2、同包的其他类类体中可以访问;
代码块:在java中,使用{}括起来的代码被称为代码块;
根据其位置和声明不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)
执行顺序:static block->istatic block2->init block1->init block2->constructor
在加载的时候就执行,并且只执行一次
package bamzhy.method; public class demo3 { int i=0; //构造代码块声明的位置在类中,其他方法之外,于成员便阿玲和成员方法平行,它的执行时机:初始化对象的时候执行 //在构造方法之前执行 { i = 0; System.out.println("init block1"); } { System.out.println("init block2"); } //静态代码块,声明位置,同初始化代码块 static{ System.out.println("static block1"); } static { System.out.println("static block2"); } static { System.out.println("static block2"); } public demo3() { i = 30; System.out.println("constructor"); } public static void main(String[] args) { demo3 demo3 = new demo3(); demo3.test(); new demo3();//无论你new多少次,static只会执行一次(轮) } public void test(){ //局部代码块 int i; { System.out.println("我是局部代码块"); } } }
继承:
语法声明:继承只能发生在“类之间”;虽然继承的语义是,父类子类都应该有,但是java中可以通过权限修饰符来控制让不让子类继承某些东西。
[修饰符]class 类名extends要继承的类名;
只有private可以阻止子类继承父类的某些(某些成员变量或者成员方法);
子类可以访问直接父类Father中的成员变量,也可以在子类中访问祖先类的成员,可以调用祖先类中的方法;
package bamzhy.object; public class demo1 extends Son { public static void main(String[] args) { Son s=new Son(); } } class GrandFather{ double d=10.1; private int testPrivate=100; public void showGrandFather(){ System.out.println("showGrandFather"); } } //Father继承GrandFather class Father extends GrandFather{ int i=10; public void testGrandFather(){ System.out.println(d); showGrandFather(); //System.out.println(testPrivate); } } class Son extends Father{ public void testFather(){ System.out.println(i); System.out.println(d); showGrandFather(); } }
子类的初始化:
1、子类对象的成员初始化之前,必须完成父类或祖先类对象的成员的初始化;
2、子类初始化有两种:隐式初始化或者显式初始化
a、隐式初始化:当父类提供了默认的构造函数,且子类的构造函数中没有显式调用父类的构造函数;执行子类的构造函数之前会自动执行父类的构造函数;
知道执行完object的构造函数后才执行子类的构造函数(当所有父类初始化完毕才初始化子类对象)
(java当中所有java类都有一个共同的祖先object类) AextendsB,BextendsC...ZextendsObject
package bamzhy.object; public class demo2 { public static void main(String[] args) { //初始化顺序 //Father2() //Son2() Son2 Son2 = new Son2(); } } class Father2{ public Father2(){ System.out.println("Father2"); } } class Son2 extends Father2{ public Son2(){ System.out.println("Son2"); } }
显式初始化:我们可以在子类中,同调用父类的构造(通过super关键字方法),在一定程度上控制父类的成员变量的初始化;
package bamzhy.object; public class demo3 { public static void main(String[] args) { } } class Father3{ int i; int j; //public Father3(){ // //} public Father3(int i){ this.i=i; System.out.println("Father3(int i)"); } public Father3(int i,int j){ this.i=i; this.j=j; System.out.println("Father3(int i,int j)"); } } class Son3 extends Father3{ /* 在子类的构造方法中,调用父类的构造方法时,super语句必须是必须是第一条语句,这个由编译器决定;、 当父类中有定义其他的构造方法(不包括默认构造方法)但是在子类中有没有显式的调用父类的肥默认构造方法,因此显式或者隐式初始化流程都无法完成 即在创建子类对象之前创建父类对象失败; */ public Son3(){ //super(); super(1,2); } }
父类中成员变量的隐藏;
package bamzhy.object; public class demo3 { public static void main(String[] args) { } } class Father3{ int i; int j; //public Father3(){ // //} public Father3(int i){ this.i=i; System.out.println("Father3(int i)"); } public Father3(int i,int j){ this.i=i; this.j=j; System.out.println("Father3(int i,int j)"); } } class Son3 extends Father3{ /* 在子类的构造方法中,调用父类的构造方法时,super语句必须是必须是第一条语句,这个由编译器决定;、 当父类中有定义其他的构造方法(不包括默认构造方法)但是在子类中有没有显式的调用父类的肥默认构造方法,因此显式或者隐式初始化流程都无法完成 即在创建子类对象之前创建父类对象失败; */ public Son3(){ //super(); super(1,2); } }
父类中成员变量的隐藏:
super:
1、可以通过super调用父亲的构造方法(只能在子类构造方法中使用)
2、super表示对父类对象的引用;
this:
1、可以表示当前对象的引用;
2、可以当做自己的构造方法;
package bamzhy.object; public class demo4 { public static void main(String[] args) { Father4 father4=new Father4(2); } } class Father4{ demo4 a; public Father4(int i,int j){ this.i=i; this.j=j; this.a=new demo4(); } int i=10; int j; public Father4(){ this(1); System.out.println("Father 4()"); } public Father4(int i){ this(i,0); this.i=i; System.out.println("Father(inti)"); } }
class Son4 extends Father4{ int i=100; public void showFather(){ System.out.println("showFather()son i -"+i); System.out.println("showFather()son i -"+super.i); } }
参数传递:参数传递中的值传递:方法中的参数类型为基本数据类型
package bamzhy.method; public class Demo1 { public static void main(String[] args) { Demo1 demo1=new Demo1(); int i=9; System.out.println("main()i="+i); //当实际参数的类型是基本数据类型时,在方法调用时首先将实际参数的值复制给形式参数,改变形参的值不会影响实际参数 demo1.test(i); System.out.println("main()i="+i); } public void test(int i){ i=2*i; System.out.println("test i:"+i); } }
引用数据的参数传递
package bamzhy; public class Demo2 { public static void main(String[] args) { Demo2 demo2=new Demo2(); TestRef testRef=new TestRef(); System.out.println("main()testRef.i="+testRef.i); demo2.test(testRef); System.out.println("main()testRef.i="+testRef.i); } public void test(TestRef ref){//引用数据的参数传递 ref.i=2*ref.i; System.out.println("test ref.i="+ref.i); } } class TestRef{ int i=10; }
据说是一道面试题:
public class Demo3 { public static void main(String args[]){ Demo d1=new Demo(1); Demo d2=new Demo(2); System.out.println(d1.a); System.out.println(d2.a); function(d1,d2); System.out.println(d1.a); System.out.println(d2.a); } private static void function(Demo d1,Demo d2){ int a; a=d1.a; d1.a=d2.a; d2.a=a; } } class Demo{ int a; public Demo(int a){ this.a=a; }
}
public class Demo4 { public static void main(String args[]){ Demo11 d1=new Demo11(1); Demo11 d2=new Demo11(2); System.out.println(d1.a); System.out.println(d2.a); function(d1,d2); System.out.println(d1.a); System.out.println(d2.a); } private static void function(Demo11 d1,Demo11 d2){ //修改的内容是引用变量本身,还是引用变量所代表的的内容 Demo11 temp; temp=d1; d1=d2; d2=temp; } } class Demo11{ int a; //构造方法是一种特殊的方法 public Demo11(int a){ this.a=a; } }