1.成员变量与局部变量的区别:
①定义的位置不同:
成员变量定义在类中;
局部变量定义在方法中;
②在内存中的位置不同:
成员变量在堆中
局部变量在栈中
③生命周期不同:
成员变量随着对象的出现而出现,随着对象的消失而消失
局部变量随着方法的调用而出现,随着方法的弹栈而消失
④初始化不同:
成员变量随着对象的出现而分配空间,有默认值
局部变量随着被使用而分配空间,若只声明不开辟内存空间,没有默认值
2.传说中的匿名对象
假设有个Car类,有num,color 2个成员变量,和一个run()方法可以打印num的值,这里有2中写法:
①:Car car = new Car();
car.color="red";
car.num="5";
car.run();
②new Car().color="red";
第二种写法就是匿名对象
局限性:第②句执行完后该对象就变成了垃圾,因为并没有引用指向该对象,垃圾回收器将回收该对象所占内存。
使用匿名对象的场景:当对对象的方法进行调用,并且只需要调用一次时,可以使用之
3.继承的实质:
继承的实质是拷贝一份父类所有的成员变量和方法到自己里面,其中包括父类的私有成员变量和方法。然后便与原本的父类没有了任何关系,子类的super()方法,构造的实际也只是拷贝到自己内部的父类的代码构造出的对象。如图:
当在main函数中执行:
Student s= new Student();
s.printNum();
Person p =new Person();
p.printNum();
会发现p.printNum()的结果仍然是10;子类中的super.num=20并不能改变原本父类的num属性,改变的只是拷贝到自己内部的父类代码构造出来的对象的num属性.
而且,若父类Person有一个私有的成员变量,子类继承时也会一起拷贝过去,只是受访问权限控制,子类不能直接访问,但若父类提供一个公有的get方法,就可以通过该方法获取该私有属性,同样获得的也是拷贝的代码构造的对象所拥有的该属性。总之,无论如何,子类与它的继承的那个父类已经没有了联系,它不能改变原本那个父类的状态,它对父类的操作实际上都只是在操作它拷贝的那个副本而已。
当子类与父类有重名的成员或者方法时,并且访问权限不是private时,子类继承时会隐藏它们,若想调用之,可以用super关键字
4.构造代码块和局部代码块
构造代码块:存放各个构造函数中的相同函数,每次构造对象,构造代码块中的代码都会被执行,在类中用{}包括的代码就是构造代码块
局部代码块:可以控制局部变量的生命周期,用于优化内存空间,在main中用{}包括的代码就是构造代码块