`
jiang5495
  • 浏览: 88681 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Java继承,深度理解。不上机运行你能正确写出运行结果吗?

阅读更多
第一种类型:继承中与this 有关的问题;

父类原码如下:
public class Father {
  
	private void testOne(){
		System.out.println("这个方法是父类的   testOne 方法!");
	}
	
	public void test(){
		System.out.println("this==="+this); //运行时的this
		this.testOne();
	}
}


子类原码如下:
public class Son extends Father {
	public void testOne() {
		System.out.println("这个儿子的  testOne 方法!");
	}

	public static void main(String[] args) {
        
        Father father = new Son();
        father.test(); //假设此为第一次运行
        
        Son son=new Son();
        son.test();  //假设此为第二次运行
	}
}


1,请问第一次的运行结果与第二次的运行结果一样吗???
2,请问两次运行this分别指向什么类型???
3,请问运行结果是什么?
4,你能解释这种现象吗?



我的解答如下:
1,两次运行结果基本一样,除了两次为对象分配的哈希码不同除外;
2,两次运行过程中,this均是子类类型的引用;
3,运行结果如下:
this===com.jishi.shenzheng.Son@c17164
这个方法是父类的   testOne 方法!
this===com.jishi.shenzheng.Son@1fb8ee3
这个方法是父类的   testOne 方法!
4,我的解释是:
对于第一种情况,Father  father=new Sun();对于引用f来说子类中的testOne()方法是不可见的,
因为子类继承父类时,并没有继承testOne()方法,因为testOne()方法是私有的。故对父类来说子类的
testOne()是子类新增的方法,进行向上转型之后,新增的方法和属性将是不可见的。而父类中的this自然是
只能调用自己的testOne()方法。(注:对于this指针<向上转型后>,它先是到子类中看此方法有未override版本,
没有再到父类中找,再没有就会报错.

对于第二种情况,Son  son=new SonClass(); 大家是否觉得很其怪,为什么不是调用子类的testOne()方法,
而是调用了父类的.....这得从this 关键字说起,this 关建字只能在类的成员方法中使用,这也就是说其是与当
前这个类相关联的,而this又是一个引用,那么就很显然了,它只能是指向该类的引用,或其子类向上转型以后的引用.
也就是说在调用父类的test()方法时,this指针属于第二种情况,发生了向上转型,而上转型后,子类中的testOne()方法
就变得不可见了,分析过程同上例.



2,第二类,关于父类中私有域的继承问题;
父类代码如下:
public class Father {
	private int a1 = 1;
	protected int a2 = 2;

	int getA1() {
		return a1;
	}

	int getA2() {
		return a2;
	}
}

子类代码如下:
public class Son extends Father {
	public void test() {
		System.out.println(this.getA1());
		System.out.println(this.a2);
		System.out.println(this.getA2());
	}

	public static void main(String[] args) {
		Son b = new Son();
		b.test();
	}
}


1,子类是否继承了父类的私有变量a1?
2,子类是否能访问到父类的私有变量a1?
3,a1是在什么时候初始化的?
4,运行结果是什么?
5,你能解释这种现象吗?

我的解答如一:
1,子类没有从父类继承私有变量a1,私有变量和方法是不可以被继承的;
2,不能直接访问,但可以间接访问;
3,子类初始化时,调用父调默认构造函数,并为其变量分配空时,初始化的。
4,运行结果如下:
 
1
2
2

5,我的理解如下:
由于son类继承father类,
他继承了father类的geta1()的方法,
但没有继承他的
private int a1 = 1;
a1这个属性之所以在son类中能用
System.out.println(this.geta1());取出来的值,是用了向上转型的原因,,
jvm先在son类里面找有没geta1()这个方法,发现没有的时候就转到了他的父类去了
这个时候的this指的是father类,,
用System.out.println(this.geta1());
打印出来了值,实际上是
father的geta1()取出来的

第三类问题,静态代码块,构造函数的调用顺序这块。
这是父类的代码:
public class Father {
	static int sum=5; 
	
	static{
		System.out.println("这是父类中的静态代码块!");  
	}
	
	public Father(){
		System.out.println("父类的构造函数被调用了!");
	}
	
	
}


这是子类的代码:
public class Son extends Father {
	
	static{
	  System.out.println("这是子类中的静态代码块!");	
	}
    
	public Son(){
		System.out.println("这是子类的构造函数");
	}
	
	public static void main(String[] args) {
	         Father.sum=5;
		new Son();
	}
}



1,Father.sum=5;这句话会引发输出吗?
2,静态代码块是什么时候被触发的?
3,构造函数的调用顺序?
4,静态代码块的调用顺序?
5,运行结果?


我的解答:
1,Father.sum=5;这句话会引发输出。因为它会导致你类被加载,些时静态代码块会被执行;
2,静态代码块是在类被加载时执行的,且仅执行一次;
3,当然是先调用父类的构造函数,再调用子类的构造函;
4,先调用父类的静态代码块,再调用子类的静态代码块;
5,运行结果如下:
这是父类中的静态代码块!
这是子类中的静态代码块!
父类的构造函数被调用了!
这是子类的构造函数




第四类,涉及组合类的相关问题,综合前面的一些东西,稍微多一点东西;

父类与子类的源代码与上相同!

祖母的源代码如下:
public class GrandMother {
  public GrandMother(){
	  System.out.println("祖母的构造函数被调用了!");
  }
}

母亲的源代码如下:
public class Mother extends GrandMother {
  
	public Son son=new Son();
	public Mother(){
		System.out.println("母亲的构造函数被调用了!");
	}
	public static void main(String[] args){
	  new Mother();
  }
}



1,是继承的类的构造优先还是组合的构造优先??
2,该程序的运行结果是什么?

我的解答:
1,是优先运行继承了,而后运行组合的,最后才是运行自己的构造函数;
2,运行结果如下:
祖母的构造函数被调用了!
这是父类中的静态代码块!
这是子类中的静态代码块!
父类的构造函数被调用了!
这是子类的构造函数
母亲的构造函数被调用了!


当然以上只是个人理解,概不负刑事责任,欢迎讨论!
5
1
分享到:
评论
3 楼 Mr_lee_2012 2012-07-25  
来过。马克。
2 楼 fy616508150 2010-08-04  
楼主辛苦了``
1 楼 j1a1v1a1 2010-08-04  

相关推荐

Global site tag (gtag.js) - Google Analytics