javase-继承

一.继承的优点

1:提高了代码的复用性。

2:让类与类之间产生了关系,提供了另一个特征多态的前提。

二.继承的特点

1.java中的继承是单继承的。

2.但允许多重继承,a继承b,b继承c,a就继承c。

三.super

1.定义:代表是子类所属的父类中的内存空间引用。

2.super方法只能在构造方法中调用。

3.在子类的构造方法中调用super方法时,super方法必须是该方法中的第一条语句。

4.一个构造方法中只能有一个super方法。

5.可用super.属性或方法的形式调用父类的属性或方法。

6.super()与this()不能同时出现在一个构造方法中。

7.super.getClass()的问题

/**
 * date:2017年6月11日10:33:32
 * target:super.getClass()方法。
 * @author ypy
 */
class A {
	public void m1() {
		System.out.println(super.getClass().getName());//等价于getClass().getName()
													   //因为Object类中的getClass()定义为final,子类不能覆盖
													   //所以子类中调用的getClass()方法其实就是调用的父类中的getClass()方法
	}
	public void m2() {
		System.out.println(getClass().getSuperclass().getName());//此方法才能返回父类
	}
}
public class Super_getClass {
	public static void main(String[] args) {
		A a = new A();
		a.m1();
		a.m2();
	}
}
/*
 *************** jdk1.8运行结果***************
dao.A
java.lang.Object
 */


四.合成(在类中创建另一个类的对象)与继承?

1.“包含”关系就用合成,“属于”关系就用继承,继承很少用,只有必须用“上溯造型”时才用继承。

2. 为什么多用组合,少用继承?

第一、子类对父类的继承是全部的公有和受保护的继承,这使得子类可能继承了对子类无用甚至有害的父类的方法。换句话说,子类只希望继承父类的一部分方法,怎么办?

第二、实际的对象千变万化,如果每一类的对象都有他们自己的类,尽管这些类都继承了他们的父类,但有些时候还是会造成类的无限膨胀。

第三、 继承的子类,实际上需要编译期确定下来,这满足不了需要在运行内才能确定对象的情况。而组合却可以比继承灵活得多,可以在运行期才决定某个对象。

五.继承中父类对象的初始化

1.继承发生时,就在子类中封装了一个父类对象,为了正确初始化父类对象,只能在构造方法中对其初始化。

2.如果父类的构造方法为默认的构造方法,子类中默认的构造方法就会自动的发出对父类构造方法的调用。

3.如果父类的构造方法含有参数,子类中就必须自己写构造方法,而且用super调用父类的构造方法。

(先调用父类的构造方法,再调用子类的构造方法)

六.继承中一个变量的初始化顺序

/**
 * date:2017年4月20日16:03:29 
 * target:继承中构造方法执行顺序的一些问题。
 * @author ypy
 * conclusion:
 *     执行顺序:
 *     main->new RoundGlyph的对象(此时,在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零,radius=0)
 *     ->父类的构造方法->子类重写的draw方法(此时的radius还为0)->对radius赋值1->子类的构造方法
 */
abstract class Glyph {
	abstract void draw();
	Glyph() {
		System.out.println("Glyph() before draw()");
		draw();
		System.out.println("Glyph() after draw()");
	}
}
class RoundGlyph extends Glyph {
	private int radius = 1;//如果这个属性是static的,那么输出结果就为RoundGlyph.draw(), radius = 1
						   //因为在类加载的时候就为其赋值为1了
	RoundGlyph(int r) {
		radius = r;
		System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
	}
	@Override
	void draw() {
		System.out.println("RoundGlyph.draw(), radius = " + radius);
	}
}
public class JiCheng_5 {
	public static void main(String[] args) {
		new RoundGlyph(5);
	}
}
/*
 * *************** jdk1.8运行结果*************** 
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
 */


七.继承中的收尾工作

在构建finalize收尾工作时,应该首先执行子类的收尾,再是父类的收尾。
这是由于子类的收尾可能调用父类中相同的方法,要求父类组件仍然处于活动状态。

/**
 * date:2017年4月20日09:40:51
 * target:继承中的收尾工作。
 * @author ypy
 * conclusion:
 *     在构建finalize收尾工作时,应该首先执行子类的收尾,再是父类的收尾。
 *     这是由于子类的收尾可能调用父类中相同的方法,要求父类组件仍然处于活动状态。
 */
class DoBaseFinalization {
	public static boolean flag = true;
}
class Father {
	public Father() {
		System.out.println("father!");
	}
	
	@Override
	protected void finalize() throws Throwable {
		System.out.println("father finalize!");
	}
}
class Childen extends Father {
	public Childen() {
		System.out.println("childen!");
	}
	
	@Override
	protected void finalize() throws Throwable {
		System.out.println("childen finalize!");
		if (DoBaseFinalization.flag) {
			super.finalize();
		}
	}
}
public class JiCheng_4 {
	public static void main(String[] args) {
		new Childen();
		System.runFinalizersOnExit(true);//这里如果调用System.gc()方法时不会执行父类的finalize()
	}
}
/* *************** jdk1.8运行结果*************** 
father!
childen!
childen finalize!
father finalize!
 */


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值