一、
当编译器需要一个String,而只有对象的时候,自动调用toString方法
public class Test {
public String toString(){
return "caonima";
}
public static void main(String[] args) {
Test test = new Test();
System.out.println( test);
}
}
结果为caonima;
二、
如果父类没有无参构造器,子类的构造器必须使用super显式调用父类的带参构造器。
子类的构造器类型必须是小于等于父类的构造器形式,就是说如果父类没有无参构造器,则子类也不能有无参构造器,如果父类的构造器有N个,则子类的构造器形式可以是<=N个,且与父类必须一一对应。例子如下
class Game{
Game(int i){
System.out.println("Game Constructor");
}
Game(float c){
System.out.println("float");
}
}
class BoardGame extends Game{
BoardGame(int i) {
super(i);
}
}
这里子类可以只有带int参数的构造器,也可以多一个带float参数的构造器,但是不能有无参构造器,因为父类没有。
三、
惊了,居然这么快就到代理了
惊了,原来之前写的Service和DAO层的关系就是代理关系了。
就是基类作为代理类的参数,而代理类提供和基类同名同参的方法,但是方法的实现选择直接调用基类的方法。简易代理如下:
public class SpaceshipDelegariton{
private String name;
private SpaceShipControls spaceShipControls = new SpaceShipControls();
public SpaceshipDelegariton(String name){
this.name = name;
}
public void up(int velocity){
spaceShipControls.up(velocity);
}
}
class SpaceShipControls{
void up(int velocity){}
}
四、
final修饰的基本数据是不可变的,但是如果用于修饰对象参数,则该对象的引用不可变,但是内容可变
public class FinalData{
private static Random random = new Random(47);
private String id;
private final int i4 = random.nextInt(20);
static final int INT5_5 = random.nextInt(20);
private final Value v2 = new Value(22);
private final int[] a = {1,2,3,4,5,6,};
public String toString(){
return id+": "+"i4 = " + i4 + ", INT_5 = "+INT5_5;
}
public FinalData(String id){
this.id = id;
}
public static void main(String[] args) {
FinalData finalData = new FinalData("fd1");
//finalData.valueOne++; 语句报错,因为final无法改变的
finalData.v2.i++;//是可以的,只要不指定为其他对象即可,对象的自身数据可以改变
//finalData.v2 = new Value(22); 语句错误,因为重新指定了对象
for (int i=0;i<finalData.a.length;i++){
finalData.a[i]++;//可行,只要finalData.a不重新指定一个数组就可以
}
System.out.println(finalData);
FinalData finalData1 = new FinalData("fd2");
System.out.println(finalData1);
}
}
class Value{
int i;
public Value(int i){
this.i = i;
}
}
//这里还有一点要注意,static final 和final :static final修饰的数据一旦被创建,则作为静态数据一直存储一直不可变,而单纯的final则是每个对象创建的时候赋予一次,而不一定是一直不可变。
//这里还有,就是如果一个class是final的则该class不可以被继承所有的包装类还有String都是final的。注意这些包装类的引用都是值传递
五、
继承和初始化,首先初始化父类的static,然后初始化子类的static,然后运行父类非static数据,然后父类构造器,然后子类的非static,然后子类构造器
代码如下
public class Shit extends Insect {
private int k = printInit("子类的实例数据");
private static int x2 = printInit("子类的静态数据");
static {
System.out.println("子类的静态初始化");
}
{
System.out.println("子类的实例代码块");
}
public Shit(){
System.out.println("子类的构造器");
System.out.println("k = "+k);
System.out.println("j = "+j);
}
public static void main(String[] args) {
System.out.println("子类的静态方法d");
Shit m = new Shit();
}
}
class Insect{
private int i = 9;
protected int j;
protected int caonima = printInit("父类的实例数据");
private static int x1 = printInit("父类的静态数据") ;
static {
System.out.println("父类的静态代码块");
}
{
System.out.println("父类的实例代码块");
}
Insect(){
System.out.println("父类的构造器");
System.out.println("i = "+i+", j = "+j);
j=39;
}
static int printInit(String s){
System.out.println(s);
return 47;
}
}
结果如下
父类的静态数据
父类的静态代码块
子类的静态数据
子类的静态初始化
子类的静态方法d
父类的实例数据
父类的实例代码块
父类的构造器
i = 9, j = 0
子类的实例数据
子类的实例代码块
子类的构造器
k = 47
j = 39