您的位置:首页 > 编程语言 > Java开发

java创建对象详解和多态问题

2015-01-07 16:20 381 查看
一、 java 构造方法不等于创建对象而是初始化对象,new 关键字分配内存和创建对象的。

二、Test test = new Test();

有人用上面的表达式来说明构造方法返回对象引用,这是明显错误的。new关键字有两个作用。

一是分配内存,创建对象。

二是调用构造方法,完成对象的初始化工作。

完成这两步之后,才算创建了一个完整的Java对象。

因此,得到的引用是new指令的结果,不是构造方法的返回值,因为构造方法没有返回值。

有一点需要注意:new指令创建对象,同时使对象的各个字段得到其默认值,比如整数为0,浮点数为0.0,引用为null,boolean为false等。也就是说在构造方法执行之前,各个字段都有默认值了。

通过上面说明,我们明确了构造方法的职能(初始化new指令创建的对象,得到一个状态合法的对象,完成对象的

创建过程)。任何类都有构造方法,但是new指令只能创建非抽象类的对象。

三、父类的构造方法中调用被子类重写的方法有多态现象。

如下:

class Father{   
    private int i = 5;   
    public Father() {   
        System.out.println("Father's i is " + this.i);   
        test();  
    }   
    public void test(){   
        System.out.println(this.i);   
    }   
}   
  
class Son extends Father{   
    private int i = 55;   
  
    public Son() {   
        System.out.println("Son's i is " + this.i);   
    }   
  
    @Override  
    public void test() {   
        System.out.println(this.i);   
    }   
  
}   
public class Test {   
    public static void main(String[] args) {   
        new Son();   
    }   
}


结果是:

Father's i is 5

0

Son's i is 55

结合第一点,构造方法调用之前,首先是new指令创建了一个对象,并将各个成员初始化为其默认值。下面看构造方法的调用过程。

子类构造方法会调用父类构造方法,父类构造方法首先打印Father's i is 5。然后调用test()方法,注意,我们创建的是Son类的对象,所以test()方法调用的是Son类定义的test()方法,也就是说发生了多态。我们再去看Son类中test方法的实现,就是简单的输出this.i,为什么是0呢,别忘了我们还没有执行子类的构造方法啊,所以此时子类的i还是new指令初始化得到的0。好,test()方法执行完了,总算回到子类构造方法继续执行,先把i赋值为55,下面的输出语句Son's
i is 55也就不难理解了。

在构造方法中调用方法要特别注意这种多态现象。

如果有多层继承关系,也是一样,如下:
<span style="font-size:18px;">public class Duotai {
	public static void main(String[] args) {
		new Sunzi();
	}
}

class Father {
	private int a = 10;

	public void test() {
		System.out.println("father=" + this.a);
	}

	public Father() {
		System.out.println("father constract=" + this.a);
		test();
	}
}

class Son extends Father {
	private int b = 1;

	public Son() {
		System.out.println("son constract=" + this.b);
		test();
	}

	@Override
	public void test() {
		System.out.println("son =" + this.b);
	}
}

class Sunzi extends Son {
	private int c = 100;

	public Sunzi() {
		test();
	}

	@Override
	public void test() {
		System.out.println("sunzi=" + this.c);
	}
}</span>


结果为:
father constract=10

sunzi=0

son constract=1

sunzi=0

sunzi=100

在继承抽象类中也是一样:

public abstract class Super { 
<span style="white-space:pre">	</span>public Super(){ 
<span style="white-space:pre">	</span>print(); 
} 
<span style="white-space:pre">	</span>public abstract void print(); 
} 

public class Sub extends Super{ 
<span style="white-space:pre">	</span>private int i = 10; 
<span style="white-space:pre">	</span>public void print(){ 
<span style="white-space:pre">	</span>System.out.println(i); 
} 
public static void main(String args[]){ 
<span style="white-space:pre">	</span>Sub sub = new Sub(); 
<span style="white-space:pre">	</span>sub.print(); 
} 
} 

Output: 
0 
10
这个涉及到类的初始化的问题

当你入口类Main方法里掉用Sub sub = new Sub(); 触发Sub类初始化,但他发现他有父类Super,而Super类没有初始化,所有先初始化父类,当初始化父类的时候,他的构造方法调用了一个抽象方法,所以找到子类的实现,(注意:这个时候的i值是0,默认值),所有输出0,之后初始化子类Sub,
i的值是10,当调用print方法时候输出10

抽象类不能来被实例化,因为它可能是一个不完整的类,里面可能包含抽象方法,抽象方法没有方法体,没有实现,所以子类继承抽象类后,实现了它的方法体,子类就是一个具体的类,可以被实例化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: